gpt4 book ai didi

ruby - 这个动态方法定义如何以及为什么起作用?

转载 作者:数据小太阳 更新时间:2023-10-29 07:10:11 24 4
gpt4 key购买 nike

下面的代码是如何工作的,更重要的是,它为什么这样工作?

class Example
def one
def one
@value = 99
end
puts "Expensive Call"
@value = 99 # assume its expensive call
end
end

ex = Example.new
puts ex.one # => "Expensive Call"; 99
puts ex.one # => 99

这里,在第一次调用方法 one 时,Ruby 执行外部的 one 方法,但在后续调用中,它只执行内部的 one > 方法,完全绕过外部 one 方法。

我想知道它是怎么发生的,为什么会这样。

最佳答案

它是如何工作的

Ruby 允许您在运行时重新定义类,因为 classdef 实际上是可执行代码。在您的示例中,代码执行以下操作:

  1. 定义一个 Example#one 方法,该方法将在调用实例方法时(重新)定义 Example#one 方法。
  2. 出于实际目的,在调用外部实例方法之前不会执行内部def。 (吹毛求疵的人可能会合理地争论这个定义,但这会涉及解析器/解释器的细节,而这些细节对于本次讨论的目的来说并不重要。)
  3. 您定义了一个名为“ex”的 Example 实例。
  4. 您在 ex 上调用实例方法,它定义了一个具有相同名称的方法。
  5. 当您再次调用实例方法时,将使用新方法代替旧方法。

为什么有效

基本上,最后一个方法的定义replaces any earlier definitions在该 namespace 中,但这些方法实际上是新对象。您可以按如下方式查看此操作:

def my_method
puts 'Old Method'
puts self.method(:my_method).object_id
def my_method
puts 'New Method'
puts self.method(:my_method).object_id
end
end

如果您在 irb 或 pry session 中运行它,您可以看到在运行时重新定义的方法:

> my_method; puts; my_method
Old Method
8998420

New Method
8998360

正如您通过不同的对象 ID 所看到的,即使方法具有相同的名称并附加到相同的对象(通常是控制台上的main),它们实际上是不同的方法对象。但是,由于这些方法是用相同的名称定义的,因此当实例执行 method lookup 时,只会找到最新的定义。 .

关于ruby - 这个动态方法定义如何以及为什么起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11384654/

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