是否可以使用块定义一个Ruby单例方法? [英] Is it possible to define a Ruby singleton method using a block?
问题描述
所以,我想为一个对象定义一个singleton方法,但我想使用一个闭包。
例如,
def define_say(obj,msg)
def obj.say
puts msg
end
end
o = Object.new
define_say o,hello world!
o.say
这不起作用,因为通过def定义了一个单例方法,不是一个闭包,所以我得到一个异常,msg是一个未定义的变量或方法。
我想做的就像使用define_method方法在Module类中,但是据我所知,这只能用于在类上定义一个方法...但我想要一个Singleton方法...
所以,我想写这样的东西:
def define_say(obj,msg)
obj.define_singleton_method(:say){
puts msg
}
end
有没有人知道我可以如何实现这一点,而无需创建一个方法来存储一个Proc,然后在单一方法中使用Proc? (基本上,我想要一个干净,非黑客的方式这样做)
这里有一个答案,寻找
def define_say(obj,msg)
#获取obj的singleton类的句柄
metaclass = class<< obj;自; end
#添加使用define_method而不是def x.say的方法,所以我们可以使用闭包
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
我是S
=> nil
有关更多信息(和一个小图书馆, >
http://viewsourcecode.org/why/ hacking / viewingMetaclassesClearly.html
另外,如果你是一个红宝石程序员,而你还没有读过,现在就去吧!
So, I want to define a singleton method for an object, but I want to do it using a closure.
For example,
def define_say(obj, msg)
def obj.say
puts msg
end
end
o = Object.new
define_say o, "hello world!"
o.say
This doesn't work because defining a singleton method via "def" is not a closure, so I get an exception that "msg" is an undefined variable or method.
What I would like to do is something like using the "define_method" method in the Module class, but as far as I can tell, this can only be used to define a method on a class... but I want a Singleton Method...
So, I would love to write it something like this:
def define_say(obj, msg)
obj.define_singleton_method(:say) {
puts msg
}
end
Does anyone know how I can achieve this without having to create a method to store a Proc and then use the Proc within a singleton method? (basically, I want a clean, non-hacky way of doing this)
Here's an answer which does what you're looking for
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
Usage (paste from IRB)
>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil
For more info (and a little library which makes it less messy) read this:
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
As an aside, If you're a ruby programmer, and you HAVEN'T read that, go do it now~!
这篇关于是否可以使用块定义一个Ruby单例方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!