如何在模块中对类方法进行别名?

我正在使用Ruby v1.9.2和Ruby on Rails v3.2.2 gem。 我有以下模块

module MyModule extend ActiveSupport::Concern included do def self.my_method(arg1, arg2) ... end end end 

我想为类方法 my_method添加别名。 所以,我说了以下( 不工作 )代码:

 module MyModule extend ActiveSupport::Concern included do def self.my_method(arg1, arg2) ... end # Note: the following code doesn't work (it raises "NameError: undefined # local variable or method `new_name' for #"). def self.alias_class_method(new_name, old_name) class << self alias_method new_name, old_name end end alias_class_method :my_new_method, :my_method end end 

换句话说,我想扩展Module类,以便在MyModule添加一个alias_class_method方法。 但是,我想让它工作并在我的所有Ruby on Rails应用程序中都可用

  1. 我应该把文件放在Module类的Ruby核心扩展中? 也许在Ruby on Rails lib目录下?
  2. 我应该如何正确地“扩展”核心扩展文件中的Module类?
  3. 这是正确的方法吗? 也就是说,例如,我应该“扩展”另一个类( ObjectBasicObjectKernel ,…)而不是Module ? 或者,我是否应该完全避免实施上述核心扩展?

但是, 更重要的是,是否有一个Rubyfunction可以实现我想要完成的function,这样我就不必扩展它的类了?

您可以使用define_singleton_method将旧方法包装在新名称下,如下所示:

 module MyModule def alias_class_method(new_name, old_name) define_singleton_method(new_name) { old_name } end end class MyClass def my_method puts "my method" end end MyClass.extend(MyModule) MyClass.alias_class_method(:my_new_method, :my_method) MyClass.my_new_method # => "my method" 

回答你的评论,你不必手动扩展每一堂课。 define_singleton_methodObject类中实现。 所以你可以简单地扩展Object类,所以每个类都应该有可用的方法……

 Object.extend(MyModule) 

把它放在Rails应用程序的初始化程序中,你应该好好去……

我在这个网站上找到了答案: http : //engineering.lonelyplanet.com/2012/12/09/monitoring-our-applications-ruby-methods/

解决方案是将class_eval与块一起使用。 这样就可以使用封闭范围内的变量。

 module Alias def trigger @trigger = true end def method_added(name) if @trigger @trigger = false with_x = "#{name}_with_x" without_x = "#{name}_without_x" define_method(with_x) do "#{send(without_x)} with x" end alias_method without_x, name alias_method name, with_x end end def singleton_method_added(name) if @trigger @trigger = false with_x = "#{name}_with_x" without_x = "#{name}_without_x" define_singleton_method(with_x) do "singleton #{send(without_x)} with x" end singleton_class.class_eval do alias_method without_x, name alias_method name, with_x end end end end class TestAlias extend Alias trigger def self.foo 'foo' end trigger def bar 'bar' end end TestAlias.foo # => 'singleton foo with x' TestAlias.new.bar # => 'bar with x' 

如果您没有singleton_class那么您应该升级您的Ruby版本。 如果那是不可能的,你可以这样做:

 class Object def singleton_class class << self self end end end 

接受的答案令人困惑,但没有奏效。

 class Module def alias_class_method(new_name, old_name) define_singleton_method(new_name, singleton_method(old_name)) end end module MyModule def self.my_method 'my method' end end MyModule.alias_class_method(:my_new_method, :my_method) MyModule.my_new_method # => "my_method"