class_evalとclass << classNameの違いは何ですか?
-
28-10-2019 - |
質問
私はルビーのスターターです。これらは両方とも非常に似ていることがわかりました(出力内)が、以下のコンテキストの違いを理解できませんでした。たとえば、クラスがあります
class Say
def self.hello
puts "hello"
end
end
そして、このように拡張することができます
class << Say
def hi
puts "hi"
end
end
また、このように
Say.class_eval do
def self.bye
puts "bye"
end
end
いつ使用すればよいですか <<
そしていつ class_eval
?
解決
class_eval
本当に何の関係もありません class << className
.
A.class_eval do
...
end
に相当します
class A
...
end
いくつかの違いがあります。 class_evalは、ブロック(または文字列を無視する)を使用します。これは、含有する字句範囲で閉じることを意味します。つまり、周囲の範囲からローカル変数を使用できます。共通のクラスブロックは、まったく新しい範囲を導入します。同様に、ブロックを作成して、多くの異なるclass_evalに渡すことができ、ブロックの本文はclass_evalをオンにしているクラスのコンテキストで実行されます。
class << className
のシングルトンクラスを開きます className
, 、クラスメソッドを定義できるようにします。
class << A
def foo
...
end
end
と同じです
def A.foo
...
end
RubyのすべてのオブジェクトがSingletonクラスを持っている場合(ほぼ)クラスである場合、それらはオリークラスの方法であり、これら2つの構文のいずれかを使用してそれらの方法を定義できることに注意してください。の利点 class << obj
主に、多くのシングルトンメソッドを一度に定義している場合です。
他のヒント
すでに言ったように、class_evalは本当に関係がありません
class <<self
あなたの例で同じことをしているように見えても(効果は類似していますが、同じことはしませんが、微妙な違いがあります)。
2番目のフォームの使用法がはるかに明確になる別の例を次に示します。
class A
end
a = A.new
b = A.new
class <<b
def say_hi
puts "Hi !"
end
end
b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method
AとBはどちらも同じクラスAのオブジェクトですが、Bのメタクラスにメソッドを追加したため、この方法はBオブジェクトでのみ使用できます。