a
Tutaj oceniasz a
, który nie jest zdefiniowany. Dlatego otrzymujesz wyjątek.
a || 1
Tutaj nadal musiał ocenić a
celu określenia wartości logicznej wypowiedzi. Podobnie jak wyżej, a
nie jest zdefiniowany. Dlatego otrzymujesz wyjątek.
a = a || 1
Tutaj a
jest zdefiniowane. Jest zdefiniowana jako niezainicjowana zmienna lokalna. W Ruby niezainicjowane zmienne oceniają się na nil
, więc prawa strona ekspresji przypisania ocenia na nil || 1
, która ocenia na 1
, więc wartość zwrotna przypisanej ekspresji wynosi 1
, a efektem ubocznym jest to, że a
jest inicjowane na 1
.
EDYTOWANIE: Wydaje się, że jest pewne zamieszanie, gdy zmienne zostaną zdefiniowane i kiedy zostaną zainicjowane w Ruby. Wartość zdefiniowana w czas analizy, ale została zainicjowana w runtime. Możesz go zobaczyć tutaj:
foo # => NameError: undefined local variable or method `foo' for main:Object
foo
jest niezdefiniowany.
W tym miejscu zdefiniowano foo
, mimo że linia nigdy nie zostanie wykonana. Fakt, że linia nigdy nie zostanie wykonana, jest zupełnie nieistotny, ponieważ interpreter nie ma z tym nic wspólnego: zmienne lokalne są definiowane przez analizator składni, a analizator składni oczywiście widzi tę linię.
foo # => nil
nie ma błędu, ponieważ foo
jest zdefiniowana, a ocenia się nil
ponieważ jest niezainicjowany.
Duplikat http://stackoverflow.com/questions/1462407/ruby-edge-cases –