Ruby-Variablendefinition [duplizieren]

8
    

Diese Frage hat hier schon eine Antwort:

    

Ich stolperte über ein merkwürdiges Verhalten im Rubin bezüglich variabler Definition (und verlor unterwegs eine Schachtel Donuts):

%Vor%

Warum wirft a.nil? undefined local variable nicht? Schauen Sie sich zum Beispiel Python an (wollte es nur mit einer interpretierten Sprache vergleichen):

%Vor%

In einer kompilierten Sprache würde dies nicht einmal kompilieren.

  • Bedeutet dies, dass Ruby einen Verweis auf diese Variable behält, selbst wenn sie diesen Code nicht durchlaufen hat?
  • Wenn ja, wie tief wird das ifs / else für die Variablendefinition berücksichtigt?

Ich kann wirklich nicht glauben, dass dies das erwartete Verhalten in Ruby ist. Und es ist nicht irb-spezifisch, läuft es in einem Ruby / Rails-Code-Block gibt das gleiche Ergebnis.

    
jlhonora 27.02.2015, 12:35
quelle

2 Antworten

3

In Ruby gibt es eine Zweideutigkeit zwischen der Referenzierung einer lokalen Variablen und einer an den impliziten Empfänger gesendeten Nachricht ohne eine Argumentliste. Das bedeutet

%Vor%

kann entweder bedeuten "lokale Variable dereferenzieren" oder "Nachricht foo an self ohne Argumente senden", d. h. sie könnte entweder äquivalent zu

sein %Vor%

oder

%Vor%

Diese Mehrdeutigkeit wird bei parse time aufgelöst. Wenn der Parser eine Zuweisung zu foo vorfindet, behandelt er foo ab diesem Zeitpunkt als lokale Variable, unabhängig davon, ob die Zuweisung tatsächlich ausgeführt wird oder nicht. (Das kann der Parser ja auch nicht statisch feststellen. Denken Sie nur an if rand > 0.5 then foo = 42 end .)

  

In einer kompilierten Sprache würde dies nicht einmal kompilieren.

Es gibt keine kompilierte Sprache. Compilation und Interpretation sind Eigenschaften des Compilers oder Interpreters (duh!), Nicht der Sprache. Sprachen werden weder kompiliert noch interpretiert. Sie sind nur .

Jede Sprache kann mit einem Compiler implementiert werden und jede Sprache kann mit einem Interpreter implementiert werden. Die meisten Sprachen haben Implementierungen kompiliert und interpretiert (zB C hat GCC und Clang, die Compiler sind, und Cint und Cling, die Interpreter sind, Haskell hat GHC, das ist ein Compiler, und Hugs, das ist ein Interpreter).

>

Viele moderne Sprachimplementierungen haben beide in der gleichen Implementierung entweder in verschiedenen Phasen (z. B. YARV und MRuby kompilieren Ruby-Quellcode zu internem Bytecode und interpretieren diesen Bytecode) oder in einer Mixed-Mode-Engine (z. B. der HotSpot JVM) Interpretiert und kompiliert JVM-Bytecode, je nachdem, was mehr Sinn macht) oder beides (zB Rubinius kompiliert in der ersten Phase Ruby-Quellcode zu Rubinius-Bytecode und kompiliert dann diesen Bytecode in nativen Code und interpretiert ihn, je nachdem, was mehr Sinn macht) .

Tatsächlich werden alle aktuell existierenden Ruby-Implementierungen kompiliert: YARV und MRuby kompilieren zu ihren eigenen internen Bytecode-Formaten, Rubinius, MacRuby, MagLev und Topaz kompilieren zu ihren eigenen internen Bytecode-Formaten, kompilieren dann < em> das zu nativem Code, kompiliert JRuby zu JVM-Bytecode (den die JVM möglicherweise weiter kompiliert), kompiliert IronRuby zu CIL-Bytecode (den das VES möglicherweise kompilieren kann oder nicht).

Die Tatsache, dass sich Ruby auf diese Weise verhält, liegt an der Sprachspezifikation. Nicht weil Ruby "interpretiert" wird, denn eigentlich ist es nicht. Die einzige rein interpretierte Implementierung von Ruby war MRI und sehr frühe Versionen von JRuby, und beide sind seit langem im Ruhestand.

    
Jörg W Mittag 27.02.2015, 15:11
quelle
1

Ich könnte mich irren, aber Ruby definiert Gültigkeitsbereiche für Ihre Variablen. Sie haben den globalen Gültigkeitsbereich, der $

ist

Dann haben Sie den lokalen Bereich Ihres laufenden Skripts, das Sie in der Frage demonstriert haben. Sie können die Variable innerhalb einer Methode definieren, sie ist jedoch weiterhin im lokalen Bereich des ausgeführten Skripts verfügbar.

Quelle: Ссылка

Hier wird veranschaulicht, dass lokale Variablen nicht den Anfangswert von nil haben, aber sobald sie definiert sind, nehmen sie den Wert an, den sie haben, unabhängig davon, ob sie definiert sind.

%Vor%

Der Unterschied liegt wieder bei den Variablen Global und Instanz. Selbst wenn sie nicht definiert wurden, nehmen sie automatisch den Wert Null an.

    
coding-bunny 27.02.2015 13:19
quelle