次のように、クラスのクラスメソッドを動的に定義できます。
class Foo
end
bar = %q{def bar() "bar!" end}
Foo.instance_eval(bar)
しかし、どのように反対を行いますか:remove/undefineクラスメソッド?モジュールのremove_method
およびundef_method
メソッドがこの目的に使用できると思われますが、何時間もGooglingした後に見たすべての例は、削除/定義解除のためのものでした。 )instanceメソッド。クラスメソッドではありません。あるいは、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は、Fooの固有クラス(別名「シングルトンクラス」)を作成し、固有クラスのスーパークラスをFooのスーパークラスに設定してから、Fooのスーパークラスを固有クラスに設定します。
Foo -------------> Foo(eigenclass) -------------> Object
super def bar super
そのため、メソッドバーを削除するには、class <<Foo
を使用して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
はそのクラスから削除しますが、スーパークラスまたはこのクラスで拡張された他のモジュールなどで定義されます。
メソッドは2つの簡単な方法で削除できます。抜本的な
Module#undef_method( )
継承されたものを含むすべてのメソッドを削除します。キンダー
Module#remove_method( )
レシーバからメソッドを削除しますが、継承されたメソッドはそのままにします。
以下の2つの簡単な例を参照してください-
undef_methodを使用した例1
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
結果-main.rb:15:in ': undefined method
x 'for#(NoMethodError)
remove_methodを使用した例2
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
aクラスのx
動的に計算する名前のメソッドを削除する場合は、次のような固有クラスを使用する必要があります。
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を使用したためです。ブロックすると現在のネームスペースが表示されるので、変数を使用してメソッドを動的に削除できます