删除/取消定义类方法

你可以像下面这样为一个类dynamic地定义一个类方法:

class Foo end bar = %q{def bar() "bar!" end} Foo.instance_eval(bar) 

但是,你如何做相反的: 删除/取消定义类方法? 我怀疑模块的remove_methodundef_method方法可能可以用于这个目的,但所有我看到谷歌search了几个小时后的例子是去除/定义实例方法,而不是类方法。 或者也许有一种语法可以传递给instance_eval来做到这一点。

提前致谢。

 #!/usr/bin/ruby1.8 class Foo def Foo.bar puts "bar" end end Foo.bar # => bar class <<Foo remove_method :bar end Foo.bar # => undefined method `bar' for Foo:Class (NoMethodError) 

当你定义一个像Foo.bar这样的类方法时,Ruby会把它放在Foo的特征类中。 Ruby不能把它放在Foo中,因为那样会是一个实例方法。 Ruby创build了Foo的本征类(又名“单例类”),将本征类的超类设置为Foo的超类,然后将Foo的超类设置为本征类:

 Foo -------------> Foo(eigenclass) -------------> Object super def bar super 

这就是为什么我们必须使用class <<Foo来打开Foo的本征class <<Foo来删除方法栏。

这也适用于我(不知道undef和remove_method之间是否有区别):

 class Foo end Foo.instance_eval do def color "green" end end Foo.color # => "green" Foo.instance_eval { undef :color } Foo.color # => NoMethodError: undefined method `color' for Foo:Class 

我想我不能评论阿德里安的答案,因为我没有足够的信誉,但他的答案帮助了我。

我发现: undef似乎将存在的方法完全移除,而remove_method将其从该类中移除,但它仍将在超类或其他已在此类上remove_method模块上定义,等等。

如果你想删除方法名称什么的计算dinamically,你应该使用本征类如:

 class Foo def self.bar puts "bar" end end name_of_method_to_remove = :bar eigenclass = class << Foo; self; end eigenclass.class_eval do remove_method name_of_method_to_remove end 

这种方式比其他答案更好,因为我在这里使用class_eval块。 正如你现在阻止看到当前命名空间,所以你可以使用你的variables来消除方法dinamically

您可以通过两种简单的方法删除一个方法。 激烈

 Module#undef_method( ) 

删除所有方法,包括inheritance的方法。 仁慈

 Module#remove_method( ) 

从接收方中删除了这个方法,但是它只保留了inheritance的方法。

看下面2个简单的例子 –

例1使用undef_method

 class A def x puts "x from A class" end end class B < A def x puts "x from B Class" end undef_method :x end obj = B.new obj.x 

result – main.rb:15:在': undefined method x'for#(NoMethodError)

例2使用remove_method

 class A def x puts "x from A class" end end class B < A def x puts "x from B Class" end remove_method :x end obj = B.new obj.x 

结果 – $ ruby​​ main.rb

x从A类

Object.send(:remove_const,:Foo)