删除/取消定义类方法
你可以像下面这样为一个类dynamic地定义一个类方法:
class Foo end bar = %q{def bar() "bar!" end} Foo.instance_eval(bar)
但是,你如何做相反的: 删除/取消定义类方法? 我怀疑模块的remove_method
和undef_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)