2014-11-15 21 views
6

Dzisiaj zetknąć się z tym dziwnym zachowaniu inline Ruby czy i blokować jeśliRóżnica między inline jeśli warunkowa i jeśli blok warunkowy w Ruby

2.0.0-p247 :001 > inline_if = 'value will not set but no error' if inline_if 
=> nil 
2.0.0-p247 :002 > if block_if 
2.0.0-p247 :003?> block_if = 'forget about setting value, I will raise an error' 
2.0.0-p247 :004?> end 
NameError: undefined local variable or method `block_if' for main:Object 
    from (irb):2 
    from /Users/myuser/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>' 

Jaka jest różnica między inline jeśli warunkowa i jeśli blok warunkowy?

+0

Gdzie zdefiniowałeś 'block_if'? – Santhosh

+0

Zarówno 'inline_if', jak i' block_if' są niezdefiniowane. Ale użycie instrukcji block if powoduje błąd podczas gdy inline nie rzuca żadnego błędu. – Hardik

+1

Oto kolejna: 'a = b.nil? => NameError: niezdefiniowana zmienna lokalna lub metoda 'b' dla głównej: Object', ale 'a = a.nil? => true'. @YuHao wyjaśnia, dlaczego. Pod koniec jednego z jego zawsze interesujących [artykułów] (http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html), Peter Cooper ujął to way: "Oznacza to, że przypisanie zmiennej, nawet jeśli nie jest uruchamiane, natychmiast przywołuje tę zmienną do istnienia." Interesujące pytanie. –

Odpowiedz

2

Zobacz Local Variables and Methods:

The local variable is created when the parser encounters the assignment, not when the assignment occurs:

a = 0 if false # does not assign to a 
p local_variables # prints [:a] 
p a    # prints nil 

W pierwszym przykładzie inline_if napotkanych najpierw zadania, dlatego jest tworzony (i ma wartość nil). Podczas gdy w drugim przykładzie, block_if jest widoczny w stanie, zanim zostanie wyświetlony w przypisaniu, co powoduje błąd.

+0

Podejrzewam, że parser musi definiować zmienną, nawet jeśli instrukcja nie jest wykonywana. Dzięki za odpowiedź. – Hardik

2

Podejrzewam, że ma coś wspólnego z analizatorem składni ruby. Ponieważ podczas pisania w linii, jeśli analizator składni Ruby rzeczywiście parsuje się od lewej do prawej strony. Tak więc w powyższej linii najpierw napotka ona metodę ustawiającą zmiennej inline_if. więc faktycznie definiuje tę zmienną o wartości nil, a następnie sprawdza pod kątem stanu if inline_if, który zostanie oceniony jako if nil.

Teraz z bloku jeśli warunek

if block_if 
    block_if = 'forget about setting value, I will raise an error' 
end 

najpierw próbuje uzyskać dostęp do block_if zmienną, która nie została jeszcze określona. stąd będzie trow błąd.

To niesamowite, że z widoku programisty oba powyższe bloki powinny być ocenione jednakowo. ale zachowują się różni

1

"Tłumacz Ruby inicjalizuje zmienną lokalną wartością zerową, gdy widzi przypisanie do niej." Zobacz this answer powiązane z prostszym pytaniem, które podkreśla kluczową część obserwowanego zachowania.

> a = a 
# => nil (and assigns nil to a) 
> b = c 
# => NameError... 

Również oglądać to zabawne video o JavaScript i Ruby dziwactw!