ruby - 如何在模块中动态调用实例方法

jer*_*rry 3 ruby

我正在尝试动态调用实例方法.我发现send,call,eval做到这一点.有动态调用类方法的例子,但我还没有弄清楚如何让它适用于实例方法.

例如

module MyModule
  def Foo
    puts "hello"
  end
end
Run Code Online (Sandbox Code Playgroud)

实例方法名称可以列出:

MyModule.instance_methods
#=> [:Foo]
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何调用该方法:

MyModule.send("Foo")
#=> NoMethodError: undefined method `Foo' for MyModule:Module

MyModule.method("Foo").call
#=> NameError: undefined method `Foo' for class `Module'

eval 'MyModule.Foo'
#=> NoMethodError: undefined method `Foo' for MyModule:Module
Run Code Online (Sandbox Code Playgroud)

如何Foo通过方法名称调用实例方法?

And*_*eko 9

免责声明:糟糕的做法,它几乎没有任何意义:

MyModule.instance_method(:Foo) # #<UnboundMethod: MyModule#Foo>
        .bind(Object)          # #<Method: MyModule#Foo>
        .call                  #=> hello
Run Code Online (Sandbox Code Playgroud)

您无法调用未绑定的方法,因此必须先将其绑定到某个对象.

参考文献:


如果你使用方法单例方法会容易得多:

module MyModule
  def self.Foo
    puts "hello"
  end
end

MyModule.Foo
#=> "hello"
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用module_function(在使用此选项时,阅读方法对包含对象的可见性):

module MyModule
  def Foo
    puts "hello"
  end
  module_function :Foo
end

MyModule.Foo
#=> "hello"
Run Code Online (Sandbox Code Playgroud)

另一个人正在使用extend self:

module MyModule
  def Foo
    puts "hello"
  end

  extend self
end

MyModule.Foo
#=> "hello"
Run Code Online (Sandbox Code Playgroud)

PS在方法名称中使用大写字母并不常见.在Ruby中它是非常罕见的情况,它可以使用,你的情况是100%而不是一个:)

  • "module_function"和"extend self"都值得一提. (2认同)