2013-02-06 7 views
8
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" 

Hier Symbol funktioniert wie erwartet, aber hier:Verständnis Ruby Symbol als Methodenaufruf

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

warum : s hier gedruckt wird ?? Ich verstehe nicht den Grund dafür. Kann mir bitte jemand erklären?

Antwort

2

Sie legen den Wert von s1 auf: s, also warum würden Sie erwarten, dass es etwas anderes zurückgibt?

Wenn Sie sich die Ruby-API für die Object-Klasse ansehen, sehen Sie sowohl Object#send als auch Object#method ein Symbol als Parameter, so dass das oberste Beispiel ebenfalls vollständig erwartet wird.

3

Von https://stackoverflow.com/a/1255362/509710:

p foo tut foo.inspect puts, dh den Wert von inspect statt to_s druckt, die für das Debuggen besser geeignet ist (weil man zB den Unterschied zwischen 1 sagen, "1" und "2\b1", die Sie kann nicht beim Drucken ohne inspizieren).

+0

Hey ich bekomme es jetzt ... es war dumm von mir, ich weiß nicht den Unterschied zwischen p und puts.Danke – sunny1304

14

Symbole sind eine Art leichte Zeichenfolgen (obwohl sie keine Zeichenfolgen sind). Die Methoden send() und method() können Zeichenfolgen oder Symbole annehmen. der eine wird in den anderen in den anderen umgewandelt (nicht sicher welcher) und dann führt Ruby die Methode mit dem passenden Namen aus. Daher entspricht A.send(:text)A.text(). Wenn Sie eine Variable namens methodName = :text hätten, könnten Sie aber nicht A.methodName() tun.

Symbole sind keine Variablen, daher können Sie einem Symbol keinen Wert zuweisen. In Ihrem Beispiel hat das Symbol :s keinen Bezug zur Variablen s (trotz der Tatsache, dass sie den gleichen "Namen" haben, vorangestellt mit einem Doppelpunkt macht es ein Symbol anstelle einer Variablen). Sie weisen der Variablen s einen Zeichenfolgenwert zu, sagen aber, dass sie das Symbol :s drucken soll, was sie tut.

+0

Dies ist eine Antwort (er sagte widerwillig) – DanSingerman

0

Symbole sind nur eine spezielle Art von Zeichenfolge, die für die Laufzeit effizienter ist. Das ist es. Sie sind keine Methoden oder Variablen oder ähnliches.

Wenn Sie A.send(:test) tun, ist alles, was Sie tun, sagen "Hey, A, rufen Sie die Methode namens 'test'". Sie senden nicht die Methode selbst, nur den Namen; Es ist die Logik in send, die für das Nachschlagen der tatsächlichen Methode verantwortlich ist, die aufgerufen wird.

Das gleiche gilt, wenn Sie nach der Methode mit A.new.method(:test) fragen. Alles, was Sie an method übergeben, ist der Name "test", nicht die Methode, die als "test" definiert ist. Es ist bis method, den Namen zu verwenden und finden Sie die tatsächliche Methode, damit es es zurückgeben kann, und es ist der Rückgabewert - ein Method-Objekt - das Sie tun call auf. Sie können call nicht auf einem Symbol wie tun, weil es nur ein Name ist.

2
s="test" 
s1=:s 
p :s.object_id #137448 
p s.object_id #77489950 
p s1.object_id #137448 

Ich habe es jetzt verstanden. Ich habe ein Symbol zugewiesen, aber eine Zeichenfolge erwartet.