我希望将一个方法标记为废弃的,这样使用该方法的人就可以轻松检查他们的代码并进行更新。在Java中,您可以设置@Deprecated注释来实现此目的。
那么,在Ruby中,是否有一种首选的方法(或甚至工具)来标记和检查废弃的方法?
我希望将一个方法标记为废弃的,这样使用该方法的人就可以轻松检查他们的代码并进行更新。在Java中,您可以设置@Deprecated注释来实现此目的。
那么,在Ruby中,是否有一种首选的方法(或甚至工具)来标记和检查废弃的方法?
对于几乎所有情况来说,依赖库或元编程来进行弃用处理是过度的。只需在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
# @deprecated Please use {#useful} instead
# Deprecated: Please use `useful` instead
已弃用: 表示该方法已被弃用,并将在未来版本中删除。您应该使用此选项来记录公共方法,但这些方法将在下一个主要版本中被删除。
此外,不要忘记在未来的某个版本中移除已弃用的方法(应该符合semver标准)。不要犯与Java库相同的错误。
# 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.
0
表示八进制,因此应该将其删除。 - Matt Whippledeprecate :initialize, UseThisClassInstead, 2017, 5
。 - Jon Kern使用ActiveSupport
:
class Player < ActiveRecord::Base
def to_s
ActiveSupport::Deprecation.warn('Use presenter instead')
partner_uid
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)
warn Kernel.caller.first + " whatever deprecation message here"
当正确使用时,这将包括已弃用调用所在文件和行的绝对路径。有关Kernel::caller的更多信息,请参见此处。
您确实拥有 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
您可以使用类宏模式来实现:
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
我最终拼凑出了一种轻量级的方法:
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