在Ruby中标记不推荐使用的代码的最佳实践?
我想标记一个方法已被弃用,所以使用它的人可以很容易地检查他们的代码并追上。 在Java中,你设置@Deprecated,每个人都知道这意味着什么。
那么有没有一种首选的方法(甚至工具)来标记和检查Ruby中的弃用?
几乎所有的情况下,取决于一个图书馆或metaprogramming贬值是矫枉过正。 只要给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
如果你使用的是Yard而不是rdoc ,你的doc注释应该是这样的:
# @deprecated Please use {#useful} instead
最后,如果你坚持tomdoc ,你的评论看起来像这样:
# Deprecated: Please use `useful` instead
已弃用:表示该方法已被弃用,将在未来的版本中被删除。 你应该使用这个来logging方法是公开的,但将在下一个主要版本中被删除。
此外, 不要忘记在将来的某些版本(以及适当的版本 )中删除弃用的方法 。 不要犯与Java库一样的错误。
Ruby标准库有一个包含警告逻辑的模块: 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.
请注意,通过这种方法,您将获得有关通话发生的免费信息。
如果你想要expression意思(在有帮助的诡计之下),你可以在警告期间打印出第一行的callstack,让开发人员知道他们在哪里使用一个不赞成的调用。
这是因为我很确定这是一个性能打击。
warn Kernel.caller.first + " whatever deprecation message here"
正确使用时,这将包括文件的绝对path和使用了不build议使用的调用的行。 更多关于Kernel :: caller的信息可以在这里find
你有libdeprecated-ruby
(2010-2012,在rubygem在2015年不可用)
旨在帮助开发人员处理弃用代码的小型库。
这个想法来自于' 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
您也可以使用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)
使用ActiveSupport:
class Player < ActiveRecord::Base def to_s ActiveSupport::Deprecation.warn('Use presenter instead') partner_uid end end
生产环境中的警告在默认情况下被closures
您可以使用类macros模式,并写下这样的东西:
class Module def deprecate(old_method, new_method) define_method(old_method) do |*args, &block| warn "Method #{old_method}() depricated. Use #{new_method}() instead" send(new_method, *args, &block) end end end class Test def my_new_method p "My method" end deprecate :my_old_method, :my_method end
使用rails时,您有Module#deprecate方法。
Canivete是一个让你可以用简单而优雅的方式来废弃你的方法的gem。 在这里稍微介绍一下 。
我结束了一个轻量级的方法:
def deprecate(msg) method = caller_locations(1, 1).first.label source = caller(2, 1).first warn "#{method} is deprecated: #{msg}\ncalled at #{source}" end
然后抛弃一个方法在方法主体(或类的构造函数)中插入一个调用,
def foo deprecate 'prefer bar, will be removed in version 3' ... end
这是相当的声明,并提供与相关信息的日志logging。 我不是一个Rubyist,所以它可能需要一些调整/ YMMV。