gpt4 book ai didi

ruby - 在 Ruby 中定义一个闭包方法

转载 作者:数据小太阳 更新时间:2023-10-29 06:47:36 25 4
gpt4 key购买 nike

我正在用 ruby​​ 重新定义对象中的方法,我需要新方法作为闭包。例如:

def mess_it_up(o)
x = "blah blah"

def o.to_s
puts x # Wrong! x doesn't exists here, a method is not a closure
end
end

现在如果我定义一个 Proc,它就是一个闭包:

def mess_it_up(o)
x = "blah blah"

xp = Proc.new {||
puts x # This works
end

# but how do I set it to o.to_s.

def o.to_s
xp.call # same problem as before
end
end

有什么想法吗?

谢谢。

最佳答案

这有效(在 irb 中测试):

注意:这只会改变 str - 不是 String 的所有实例。阅读下文,详细了解为何如此有效

another_str = "please don't change me!"
str = "ha, try to change my to_s! hahaha!"
proc = Proc.new { "take that, Mr. str!" }

singleton_class = class << str; self; end

singleton_class.send(:define_method, :to_s) do
proc.call
end

puts str.to_s #=> "take that, Mr. str!"
puts another_str.to_s #=> "please don't change me!"

# What! We called String#define_method, right?

puts String #=> String
puts singleton_class #=> #<Class:#<String:0x3c788a0>>

# ... nope! singleton_class is *not* String
# Keep reading if you're curious :)

之所以有效,是因为您正在打开 str 的 singleton class并在那里定义一个方法。因为这个,以及对 Module#define_method 的调用,有一些所谓的“平面范围”,如果你使用 def to_s; ,你可以访问超出范围的变量; '任何';结束

您可能想在这里查看其他一些“元编程法术”:

media.pragprog.com/titles/ppmetr/spells.pdf


为什么它只改变str

因为 Ruby 有一些有趣的技巧。在 Ruby 对象模型中,方法调用导致接收者不仅搜索它的类(和 它的 祖先),而且搜索它的单例类(或者如 Matz 所说的那样,它是特征类)。这个单例类允许你为单个对象[重新]定义一个方法。这些方法称为“单例方法”。在上面的示例中,我们就是这样做的 - 定义一个单例方法名称 to_s。它在功能上与此相同:

def str.to_s
...
end

唯一的区别是我们在调用 Module#define_method 时使用闭包,而 def 是关键字,这会导致范围发生变化。

为什么不能更简单?

好吧,好消息是你正在用 Ruby 编程,所以尽情发疯吧:

class Object
def define_method(name, &block)
singleton = class << self; self; end
singleton.send(:define_method, name) { |*args| block.call(*args) }
end
end


str = 'test'
str.define_method(:to_s) { "hello" }
str.define_method(:bark) { "woof!" }
str.define_method(:yell) { "AAAH!" }

puts str.to_s #=> hello
puts str.bark #=> woof!
puts str.yell #=> AAAH!

而且,如果您好奇...

你知道类方法吗?或者,在某些语言中,我们称它们为静态方法?好吧,这些在 Ruby 中并不真的存在。在 Ruby 中,类方法实际上只是在 Class 对象的单例类中定义的方法。

如果这一切听起来很疯狂,请查看我上面提供的链接。如果您知道如何进行元编程,那么 Ruby 的很多功能只能被利用 - 在这种情况下,您真的很想了解单例类/方法,更一般地说,Ruby 对象模型。

HTH

-查尔斯

关于ruby - 在 Ruby 中定义一个闭包方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2495550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com