12
class A
   def test
       "Test from instance"
   end
   class << self
       def test
           "Test from class"
       end
    end
end

p A.send(:test)    # "Test from class"
p A.new.method(:test).call  # "Test from instance"

ここでシンボルは期待どおりに機能しますが、ここでは:

s="test"
s1=:s
p s1   # :s

なぜ:sがここに出力されるのですか?? その背後にある理由がわかりません。誰か説明してくれませんか?

4

5 に答える 5

18

シンボルは一種の軽量文字列です (文字列ではありませんが)。send()およびメソッドはmethod()、文字列または記号を取ることができます。1つは内部の仕組みでもう1つに変換され(どちらかはわかりません)、rubyは一致する名前でメソッドを実行します。したがってA.send(:text)、 と同等A.text()です。という名前の変数があればmethodName = :text、できますが、できませA.send(methodName)A.methodName()

シンボルは変数ではないため、シンボルに値を割り当てることはできません。あなたの例では、シンボル:sは変数とは無関係ですs(同じ「名前」を持っているにもかかわらず、コロンを前に付けると、変数ではなくシンボルになります)。変数に文字列値を割り当てていますsが、シンボルを出力するように指示し:sています。

于 2013-02-06T19:04:24.550 に答える
3

https://stackoverflow.com/a/1255362/509710から:

p fooputs を実行しますfoo.inspect。つまり、 のinspect代わりにの値を出力します。これは、デバッグにより適しています (たとえば、とto_sの違いがわかるため、inspect なしでは出力できません)。1"1""2\b1"

于 2013-02-06T18:52:41.587 に答える
2

You set the value of s1 to be :s, so why would you expect it to return anything different?

If you look at the ruby API for the Object class, you will see both Object#send and Object#method take a symbol as a parameter, so the top example is also totally expected.

于 2013-02-06T18:49:59.313 に答える
2

シンボルは、ランタイムが通常の文字列よりも効率的に処理できる特別な種類の文字列のような値です。それでおしまい。メソッドや変数などではありません。

するときA.send(:test)、あなたがしていることは、「ねえ、A、「test」という名前のメソッドを呼び出して」と言うだけです。メソッド自体を送信するのではなく、名前だけを送信します。send呼び出す実際のメソッドを検索するのは内部のロジックです。

でメソッドを要求するときも同じことが言えますA.new.method(:test)。渡すmethodのは「test」という名前だけであり、その名前で定義されたメソッドではありません。method名前を使用して実際のメソッドを見つけて、それを返すことができるようにする必要があります。それは、その戻り値 (メソッド オブジェクトcall) です。callのようなシンボル:testは名前にすぎないため、実行できません。

于 2013-02-06T19:09:47.723 に答える
2
s="test"
s1=:s
p :s.object_id  #137448
p s.object_id   #77489950
p s1.object_id  #137448

私は今それを理解しました。シンボルを割り当てていましたが、文字列を期待していました。

于 2013-02-06T19:09:53.287 に答える