我刚刚了解到 Ruby 有一种称为 的特殊方法undef_method
。它实际上取消了现有方法的定义。
您undef_method
可以<
像下面这样从 Integer 中取消定义:
class Integer
undef_method :<
end
begin
puts 1 < 2
rescue Exception => exception
puts exception
puts 1.0 < 2
end
结果如下:
undefined method `<' for an instance of Integer
true
这是可以理解的,因为 Ruby 本身是高度面向对象的,并且一切都是对象,包括其类型系统等。
但是您可以取消定义,undef_method
以使从整数取消定义变得不可能<
。
class Module
undef_method :undef_method
end
class Integer
undef_method :<
end
begin
puts 1 < 2
rescue Exception => exception
puts exception
puts 1.0 < 2
end
既然它undef_method
本身未定义,你就无法真正<
从 Integer 中取消定义。
temp.rb:6:in `<class:Integer>': undefined method `undef_method' for class Integer (NoMethodError)
undef_method :<
^^^^^^^^^^^^
from temp.rb:5:in `<main>'
因此问题是:undef_method
当 ruby 变得未定义时,它如何执行?
如果 Ruby 是编译型语言,我假设 Ruby 会先加载方法,然后执行自定义代码,这样就没问题了!但是 Ruby 是解释型语言,在执行代码之前不会加载代码。
我认为这可能会导致问题,因为如果方法在执行时未定义,Ruby 就无法判断要执行什么代码。
容易地!
看看方法是如何工作的可能会有所帮助。考虑一下
Kernel.puts(1 + 1)
。以下是按顺序发生的情况:
Kernel
。1 + 1
结果是2
。Kernel.puts
已找到。Kernel.puts
用参数 来调用2
。nil
)。现在我们
Module.undef_method(:undef_method)
以同样的方式看一下:Module
。:undef_method
,不需要额外的评估。Module.undef_method
被发现,因为还没有任何事情发生。Module.undef_method
用参数 来调用:undef_method
。Module
)。如您所见,这个“悖论”很容易解释,因为在查找方法时,该方法仍然存在。只有在查找和调用该方法后,才会在单独的步骤中将其删除,而从方法表中删除名称“undef_method”的操作不会影响已找到的方法完成执行的能力。