メソッドを再定義したいのですが、それに関連する警告は避けてください。そのために undef_method または remove_method を使用する必要がありますか?
(はい、メソッドの再定義は少しハックです。これを行っているのは、プログラム自体の実行時ではなく、単体テストの実行時に使用したいメモ化があるためです。)
メソッドを再定義したいのですが、それに関連する警告は避けてください。そのために undef_method または remove_method を使用する必要がありますか?
(はい、メソッドの再定義は少しハックです。これを行っているのは、プログラム自体の実行時ではなく、単体テストの実行時に使用したいメモ化があるためです。)
細かいマニュアルから:
undef_method(シンボル) → 自己
現在のクラスが名前付きメソッドの呼び出しに応答しないようにします。
remove_method
これを、特定のクラスからメソッドを削除すると対比してください。Ruby は引き続きスーパークラスと混合モジュールを検索して、可能な受信者を探します。
したがって、次のremove_method
ようになります。
class CC < C
remove_method :m
end
は本質的にこれの反対です:
class CC < C
def m
end
end
メソッドをクラスにdef m
追加し、 を削除します。ただし、スーパークラスにメソッドがある場合は、それが引き続き使用されます。m
remove_method :m
m
m
undef_method
、OTOHは、次のようになります。
class CC < C
def m
raise 'No, you cannot do that.'
end
end
そのundef_method
ため、実際にメソッドを削除するのではなく、そのメソッドを呼び出そうとすると Ruby にエラーを発生させる特別な内部フラグでメソッドを置き換えます。
既存のメソッドを置き換えようとしているように聞こえますが、replaceは意味的にremoveの後にadd を行うのと同じであるためremove_method
、おそらくより適切です。ただし、妄想的になりたい場合や、置換方法が整っていることを確認したい場合は、undef_method
便利です。または、何らかの理由である場所でメソッドを削除して別の場所に追加する必要がある場合undef_method
、少なくとも半分の仕事しかできなかったことがremove_method
わかりますが、スーパークラスの実装(および奇妙なバグの可能性)が残るか、かなり紛らわしいNoMethodError
。
メソッドは 2 つの簡単な方法で削除できます。抜本的な
Module#undef_method( )
継承されたものを含むすべてのメソッドを削除します。キンダー
Module#remove_method( )
レシーバーからメソッドを削除しますが、継承されたメソッドはそのままにします。
以下の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
結果 - main.rb:15:in
': 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
×Aクラスから