2016-05-16 17 views
6

In der Ruby-Programmiersprache von David Flanagan; Yukihiro Matsumoto, they state that the variable prefixes ($, @, @@) are one price we pay for being able to omit parentheses around method invocations. Kann mir das jemand erklären?Warum ermöglichen variable Präfixe in Ruby das Weglassen von Klammern in Methodenaufrufen?

+2

Gute Frage eigentlich. Ich bin mir nicht sicher, ob diese Aussage streng genommen richtig ist. Ich dachte immer, dass die Präfixe den Gültigkeitsbereich spezifizieren würden (d. H. Lokal, Instanz, Klasse, global), anstatt Variablen von Methoden zu unterscheiden (klar unterscheiden sich lokale Variablennamen von Methodenaufrufen durch den Interpreter). – Cubic

+0

Wenn Sie nach einer bestimmten Referenz fragen, geben Sie zumindest einen Link an, wenn sie online verfügbar ist. – sawa

+0

@sawa: [link] (https://books.google.co.jp/books?id=rbY5mz-_VdQC&lpg=PA7&ots=10Wd8nk-uL&pg=PA7#v=onepage&q&f=false) – Amadan

Antwort

1

Hier ist meine unreife Meinung. Wenn ich falsch liege, korrigiere mich bitte.

Angenommen, die Instanzvariablen haben kein @ Präfix, wie deklarieren wir dann eine Instanzvariable?

class MyClass 
    def initialize 
    # Here foo is an instance variable 
    self.foo = 'bar' 
    end 

    # Here foo is an instance method 
    def foo 
    end 

    def bar 
    # Call method. No doubt. 
    self.foo() 

    # Call method? Access instance variable? 
    self.foo 
    end 
end 

Im obigen Fall wird die Instanz-Variable foo mit der hypothetischen Syntax initialisiert

self.foo = 'bar' 

, weil wir eine Möglichkeit haben, muss dem Ruby-Interpreter zu sagen, dass foo auf die aktuelle Instanz gehört und nicht eine lokale Variable.

Wenn in der Methode bar Klammern beim Methodenaufruf nicht erzwungen werden, wie kann der Interpreter dann feststellen, ob self.foo ein Methodenaufruf oder ein Zugriff auf Instanzvariablen ist?

Vielleicht können wir Instanzvariablen die Schattenmethoden von Instanzen ignorieren lassen, wenn Klammern fehlen, aber dies führt zu Syntaxinkonsistenz der Sprache selbst. Zum Beispiel von außerhalb der MyClass Definition:

obj = MyClass.new 

# Call instance method 
obj.foo 

Es ist ein Beispiel Methodenaufruf, da alle Instanzvariablen von außen nicht sichtbar sind (zumindest ohne Meta-Programmierung verwendet wird). Aber die self.foo (ohne Klammern) in der Methode bar ist eine Instanzvariable Zugriff. Diese Syntaxinkonsistenz kann zu Fehlern führen. Es bringt auch Schwierigkeiten bei der Implementierung des Interpreters selbst.

Wie können Instanzmethoden Instanzvariablen überschatten? Dann müssen die Programmierer sicherstellen, dass die Namen der Instanzvariablen nicht mit den Namen der Instanzmethoden kollidieren, da andernfalls die Instanzvariablen nicht zugänglich sind. Es ist sehr schwierig, wenn eine Klasse eine lange Vorfahrenkette hat, weil man Kollisionen nicht nur in der aktuellen Klassendefinition, sondern auch in ihren Vorfahren überprüfen muss, und dies bricht die Kapselung.

In jedem Fall ist der Preis viel höher als das Hinzufügen eines Präfixes zu Instanzvariablen. Für Klassen- und globale Variablen sind die Situationen ähnlich.

0

Lässt ein Beispiel an:

def foo 
    10 
end 

p foo 
#=> 10 
foo = 'hi' 
p foo 
#=> hi 
p foo() 
#=> 10 

Wenn wir eine lokale Variable, deren Name gleich ist wie Methodenname im gleichen Umfang zu definieren, dann können wir die Bindung an Methodennamen verlieren als Variablennamen Vorrang. Um zu disambiguieren, wird man gezwungen sein, Klammern zu verwenden.

Das Buch scheint über dieses Phänomen zu erarbeiten, und Design-Entscheidung, die Flexibilität bei dem eine Notwendigkeit Symbole zu verwenden, wie @ Instanz zu schaffen gemacht Variablen zu definieren, so dass die jeweiligen Zugriffsmethoden (var & var=) ohne Klammern aufgerufen werden, und Man bekommt den Eindruck, dass man auf die Variable zugreift, obwohl man in Wirklichkeit eine Methode aufruft.

...Sie werden Satzzeichen am Anfang der Ruby-Variablen sehen Namen: Globale Variablen haben das Präfix $, Instanzvariablen sind mit dem Präfix @, und Klassenvariablen wird das Präfix @@ vorangestellt. Diese Präfixe können ein wenig gewöhnungsbedürftig sein, aber nach einer Weile können Sie die Tatsache schätzen, dass das Präfix Ihnen den Umfang der Variable zu schätzen wissen. Die Präfixe sind erforderlich, um Rubys sehr flexible Grammatik zu entschlüsseln. Eine Möglichkeit, an variable Präfixe zu denken, ist, dass sie ein Preis sind, den wir dafür bezahlen, Klammern um Methodenaufrufe weglassen zu können.