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):
In einer kompilierten Sprache würde dies nicht einmal kompilieren.
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.
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
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.
Ich könnte mich irren, aber Ruby definiert Gültigkeitsbereiche für Ihre Variablen. Sie haben den globalen Gültigkeitsbereich, der $
istDann 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.
Tags und Links ruby ruby-on-rails abstract-syntax-tree interpreted-language