sha*_*esh 5 ruby metaprogramming
以下代码如何工作,更重要的是,它为什么会这样工作?
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
Run Code Online (Sandbox Code Playgroud)
这里,在第一次调用方法时one,Ruby执行外部one方法,但是在连续调用时,它只执行内部one方法,one完全绕过外部方法.
我想知道它是如何发生的,为什么会这样.
Ruby允许您在运行时重新定义类,因为class和def实际上是可执行代码.在您的示例中,代码执行以下操作:
基本上,方法的最后一个定义替换了该命名空间中的任何早期定义,但这些方法实际上是新对象.您可以按如下方式查看此操作:
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
Run Code Online (Sandbox Code Playgroud)
如果在irb或pry会话中运行此命令,则可以看到在运行时重新定义的方法:
> my_method; puts; my_method
Old Method
8998420
New Method
8998360
Run Code Online (Sandbox Code Playgroud)
正如您可以通过不同的对象ID看到的那样,即使这些方法具有相同的名称并且附加到同一个对象(通常是控制台上的主要对象),它们实际上也是不同的方法对象.但是,由于方法是使用相同的名称定义的,因此当实例执行方法查找时,只会找到最新的定义.
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |