class String
def hello
"world"
end
end
String.class_eval {
def world
"hello"
end
}
"a".world
=> "hello"
"b".hello
=> "world"
彼らは同じことをやっているようだ - 既存のクラスにメソッドを追加します。違いは何ですか?monkey patching vs class_eval?
class String
def hello
"world"
end
end
String.class_eval {
def world
"hello"
end
}
"a".world
=> "hello"
"b".hello
=> "world"
彼らは同じことをやっているようだ - 既存のクラスにメソッドを追加します。違いは何ですか?monkey patching vs class_eval?
class_eval
を使用すると、よりダイナミックなことを行うことができます。
>> met = "hello" #=> "hello"
>> String.class_eval "def #{met} ; 'hello' ; end" #=> nil
>> "foo".hello #=> "hello"
は概念的にクラス再開(またはサルのパッチ適用)を行うclass_evalメソッド。構文上の違いがほとんどあります。あなたは(マイケルの例のように)class_eval
に文字列を渡す場合は、class String; ... end
のように文字列の中で、ほとんど同じ構文を持っています。あなたがブロックを渡す場合:String.class_eval { ... }
次のように比較しますclass_evalメソッドブロック外のローカル変数の内部
をCANリニューアルオープンクラスの内部クラス
他の答えは良いです。 class_eval
はあなたがいないその定数によって参照クラスをしたいときに使用することができたり、特定のオブジェクトにパッチを適用することを追加します。
huh = String
class huh
end
SyntaxError: (eval):2: class/module name must be CONSTANT
huh.class_eval <<-eof
def mamma
puts :papa
end
eof
"asdff".mamma
=> papa
あなたはaffectin全体のルートクラスせずに特定のオブジェクトにパッチを適用するclass_eval
を使用することができます。
obj = "asd"
obj.singleton_class.class_eval <<-eof
def asd
puts "gah"
end
undef_method :some_method
上記と同じである:
class << obj
...
end
instance_eval
いくつかの使用によって若干異なる振る舞いを持つことになります。
私はこの質問と回答は興味深い見つける: How to monkey patch a ruby class inside a method
はまたinstance_eval
対class_eval
についての質問があったが、私は便利なリンクを持っていません。