是否可以使用块定义Ruby单例方法?

时间:2020-03-06 14:44:56  来源:igfitidea点击:

因此,我想为一个对象定义一个单例方法,但是我想使用闭包来实现。

例如,

def define_say(obj, msg)
  def obj.say
    puts msg
  end
end

o = Object.new
define_say o, "hello world!"
o.say

这不起作用,因为通过" def"定义单例方法不是闭包,因此我得到一个例外,即" msg"是未定义的变量或者方法。

我想做的事情类似于在Module类中使用" define_method"方法,但是据我所知,它只能用于在类上定义方法...但是我想要Singleton方法。 ..

所以,我很想这样写:

def define_say(obj, msg)
  obj.define_singleton_method(:say) {
    puts msg
  }
end

有谁知道我如何能做到这一点而不必创建存储Proc的方法,然后在单例方法中使用Proc? (基本上,我想要一种干净,非hacky的方式来做到这一点)

解决方案

这是我们要寻找的答案

def define_say(obj, msg)
  # Get a handle to the singleton class of obj
  metaclass = class << obj; self; end 

  # add the method using define_method instead of def x.say so we can use a closure
  metaclass.send :define_method, :say do
    puts msg
  end
end

用法(来自IRB的粘贴)

>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil

欲了解更多信息(以及一个使它不那么混乱的小图书馆),请阅读以下内容:

http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html

顺便说一句,如果我们是红宝石程序员,并且还没有阅读过,那就马上开始吧!