ruby 仅从示例中移除方法

s1ag04yj  于 2023-10-17  发布在  Ruby
关注(0)|答案(2)|浏览(109)

是否可以从单个示例中删除方法?

class Foo
  def a_method
    "a method was invoked"
  end
end

f1 = Foo.new
puts f1.a_method # => a method was invoked

我可以从类中删除一个_方法,从已经创建的对象中删除:

class Foo
  remove_method(:a_method)
end

如果我从同一个对象调用一个_方法:

puts f1.a_method # => undefined method

如果我创建另一个对象:

f2 = Foo.new
puts f2.a_method # => undefined method

如何从一个特定的对象中删除一个方法?

zu0ti5jz

zu0ti5jz1#

是的,有可能:

f1.instance_eval('undef :a_method')
wnvonmuf

wnvonmuf2#

你可以在你关心的对象的单例类上调用undef_method

f1.singleton_class.undef_method(:a_method)

说明

不要混淆remove_methodundef_method。它们看起来很相似,但行为却大不相同。undef_method的文档解释为:
阻止当前类响应对命名方法的调用。与此相反,remove_method从特定类中删除方法; Ruby仍然会在超类和混合模块中搜索可能的接收器。

Module#remove_method

.将从特定模块/类的方法表中删除方法。
这并不意味着信息(例如,a_method)仍然不能发送给该类的对象。
它的行为就像你没有在那个模块/类中定义一个方法实现一样,所以常规的继承行为仍然会发生:方法解析将继续沿着祖先链向上搜索。
下面是一个示例:

class Parent
  def m = "The parent implementation"
end

class Child < Parent
  def m = "The child override"

  remove_method :m # Behaves as if `m` was commented out above
end

p Child.new.m # => "The parent implementation"

Module#undef_method

...将在Module/Class的方法表中定义一个特殊类型(VM_METHOD_TYPE_UNDEF)的特殊方法,其行为就像它有一个只引发的实现一样。
尝试调用此方法将找到此存根,并终止搜索(不向上搜索祖先链)。它的实施只是提高。

class Parent
  def m = "The parent implementation"
end

class Child < Parent
  def m = "The child override"

  undef_method :m # Behaves as if `m` was defined as `= raise NoMethodError`
end

p Child.new.m # => NoMethodError

相关问题