メソッドを再定義したいが、それに関連する警告は避けたい。 undef_methodまたはremove_methodを使用してこれを行う必要がありますか? undef_methodを使用するタイミングとremove_methodを使用するタイミングは?
(はい、メソッドを再定義すると、私はユニットテストが実行されているときに使用するいくつかのメモ化を持っているので、私はこれをやっている。少しハックですが、プログラム自体が実行されていないとき。)答えて
fine manualから:
undef_method(シンボル)→自己
は、名前のメソッドの呼び出しに応答してから現在のクラスのを防ぎます。特定のクラスからメソッドを削除する
remove_method
と対比してください。 Rubyは可能な受信機のためにスーパークラスと混在モジュールを検索します。
ので、このようなremove_method
:
class CC < C
remove_method :m
end
は、本質的にこれの逆である:
def m
がクラスにメソッドを追加します
m
class CC < C
def m
end
end
、remove_method :m
はm
を削除します。しかし、もしスーパークラスがm
メソッドを持っていれば、それはまだ使用されます。
undef_method
、OTOH、より多くのこのようなものです:だからundef_method
が実際にメソッドを削除しません。あなたはそれを呼び出そうと
class CC < C
def m
raise 'No, you cannot do that.'
end
end
、それはRubyが文句を起こす特殊な内部フラグを持つメソッドを置き換えます方法。
では、既存のメソッドを置き換えるためにしようとしているような音やを交換remove_method
は、おそらくより適切であるので、を追加し、意味的にを削除続いと同じです。しかし、あなたが妄想的になり、置換方法が適切であることを確認したい場合は、undef_method
が便利です。または何らかの理由で1つの場所でメソッドを削除して別の場所に追加する必要がある場合は、undef_method
は少なくとも、ジョブの半分しか実行しなかったと言いますが、remove_method
はスーパークラスの実装を残します)またはかなり混乱しているNoMethodError
。
メソッドを削除するには、2つの方法があります。抜本的な
Module#undef_method()
は、継承されたものを含むすべてのメソッドを削除します。
Module#remove_method()
親切が受信機からメソッドを削除しますが、それ 葉が一人でメソッドを継承しています。 2簡単な例を下に見る - main.rb - を用い
例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
結果undef_method:15: ': undefined method
X」位(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
結果 - クラスから $ルビーmain.rb
X
恐ろしい説明。 –