質問

私はルビーのスターターです。これらは両方とも非常に似ていることがわかりました(出力内)が、以下のコンテキストの違いを理解できませんでした。たとえば、クラスがあります

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オブジェクトでのみ使用できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top