在Ruby中标记弃用代码的最佳实践?

bli*_*ger 121 ruby deprecated

我想将方法​​标记为已弃用,因此使用它的人可以轻松检查其代码并赶上.在Java中你设置@Deprecated,每个人都知道这意味着什么.

那么在Ruby中标记和检查弃用是否有一种首选方式(甚至是工具)?

Rya*_*ary 155

对于几乎所有情况,根据库或元程序进行弃用都是过度的.只需在rdoc中添加注释并调用该Kernel#warn方法即可.例如:

class Foo
  # <b>DEPRECATED:</b> Please use <tt>useful</tt> instead.
  def useless
    warn "[DEPRECATION] `useless` is deprecated.  Please use `useful` instead."
    useful
  end

  def useful
    # ...
  end
end
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Yard而不是rdoc,那么您的文档评论应如下所示:

# @deprecated Please use {#useful} instead
Run Code Online (Sandbox Code Playgroud)

最后,如果您坚持使用tomdoc,请将您的评论看起来像这样:

# Deprecated: Please use `useful` instead
Run Code Online (Sandbox Code Playgroud)

不推荐使用:表示该方法已弃用,将在以后的版本中删除.您应该使用它来记录公共方法,但将在下一个主要版本中删除.


此外,不要忘记在将来(以及正确的semver'd)版本中删除已弃用的方法.不要犯与Java库相同的错误.

  • 守则是一种责任.你需要的代码越少越好.弃用有利于临时向后兼容,但随着时间的推移,它变得很残酷.如果人们*需要*使用退休方法,他们应该使用旧版本的库. (37认同)
  • 我不确定Java部分是一个"错误",而是一个巨大的向后兼容性问题(请参阅http://stackoverflow.com/questions/314540),blindgaenger可能不需要考虑他的Ruby代码. (3认同)
  • 非常好的回应.我只想添加一个链接到响应,在那里我展示了我最近使用的方法,它依赖于Ruby Std Lib:http://stackoverflow.com/questions/293981/best-practice-to-mark-deprecated -code功能于红宝石/ 23554720#23554720 (2认同)
  • @RicardoValeriano 我同意,你的回答应该被整合(或更高投票,或两者兼而有之:))。 (2认同)

Ric*_*ano 48

Ruby Standard Library有一个带有警告逻辑的模块:http://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Gem/Deprecate.html.我更倾向于以"标准"方式维护我的弃用消息:

# my_file.rb

class MyFile
  extend Gem::Deprecate

  def no_more
    close
  end
  deprecate :no_more, :close, 2015, 5

  def close
    # new logic here
  end
end

MyFile.new.no_more
# => NOTE: MyFile#no_more is deprecated; use close instead. It will be removed on or after 2015-05-01.
# => MyFile#no_more called from my_file.rb:16.
Run Code Online (Sandbox Code Playgroud)

请注意,通过这种方法,您将获得有关呼叫发生地点的免费信息.

  • 之前的正确答案已被弃用,现在应该使用Ricardo Valueriano的答案 (4认同)
  • 谢谢你的提示.我弃用了整个类,并建议使用更新的类:`deprecate:initialize,UseThisClassInstead,2017,5? (3认同)
  • 数字文字的前导"0"使其成为八进制,因此可能会被删除. (2认同)

小智 13

如果你想成为卑鄙的人(在有用的诡计下),你可以在警告期间打印出callstack的第一行,让devs知道他们在哪里使用不推荐的电话.

这是卑鄙的,因为我很确定它会受到性能影响.

warn Kernel.caller.first + " whatever deprecation message here"
Run Code Online (Sandbox Code Playgroud)

如果使用正确,这将包括文件的绝对路径和使用不推荐的调用的行.有关Kernel :: caller的更多信息,请点击此处

  • 我不认为这意味着什么.一个小的性能打击比不得不追逐被弃用的调用更好,并且比最终删除方法时更糟糕的东西要好得多. (4认同)

Art*_*jev 12

使用ActiveSupport:

class Player < ActiveRecord::Base
  def to_s
    ActiveSupport::Deprecation.warn('Use presenter instead')
    partner_uid
  end
end
Run Code Online (Sandbox Code Playgroud)

默认情况下,生产环境中的警告处于关闭状态


Kri*_*ris 10

您也可以使用ActiveSupport::Deprecation(在4.0+版本中提供),如下所示:

require 'active_support/deprecation'
require 'active_support/core_ext/module/deprecation'

class MyGem
  def self.deprecator
    ActiveSupport::Deprecation.new('2.0', 'MyGem')
  end

  def old_method
  end

  def new_method
  end

  deprecate old_method: :new_method, deprecator: deprecator
end

MyGem.new.old_method
# => DEPRECATION WARNING: old_method is deprecated and will be removed from MyGem 2.0 (use new_method instead). (called from <main> at file.rb:18)
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 7

你有libdeprecated-ruby(2010-2012,2015年不再在rubygem上提供)

一个小型库,旨在帮助开发人员使用已弃用的代码.
这个想法来自于' D'编程语言,开发人员可以将某些代码标记为已弃用,然后允许/禁止执行弃用代码的能力.

require 'lib/deprecated.rb'
require 'test/unit'

# this class is used to test the deprecate functionality
class DummyClass
  def monkey
    return true
  end

  deprecate :monkey
end

# we want exceptions for testing here.
Deprecate.set_action(:throw)

class DeprecateTest < Test::Unit::TestCase
  def test_set_action

    assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }

    Deprecate.set_action(proc { |msg| raise DeprecatedError.new("#{msg} is deprecated.") })

    assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }


    # set to warn and make sure our return values are getting through.
    Deprecate.set_action(:warn)

    assert_nothing_raised(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey } 
  end
end
Run Code Online (Sandbox Code Playgroud)