2013-06-18 10 views
9

Nie rozumiem, dlaczego eval działa tak:Ruby: eval z interpolacją strun

"123 #{456.to_s} 789" # => "123 456 789" 
eval('123 #{456.to_s} 789') # => 123 

Jak można interpolować w ciąg wewnątrz eval?

Aktualizacja:

Dziękuję, przyjaciele. Zadziałało.

Więc jeśli masz zmienną string z #{} który chcesz eval później, należy zrobić to jak poniżej:

string = '123 #{456} 789' 
eval("\"" + string + "\"") 
# => 123 456 789 

lub

string = '123 #{456} 789' 
eval('"' + string + '"') 
# => 123 456 789 
+1

Co masz na myśli przez "substytucje makro"? – sawa

+0

@sawa, miałem na myśli sekcje '# {}', edytuj je we właściwy sposób, po prostu nie wiem jak to powiedzieć po angielsku –

+1

Dobra, może chodziło ci o interpolację. – sawa

Odpowiedz

19

Co się dzieje, to eval ocenia ciąg jako kod źródłowy. Podczas korzystania cudzysłowia, łańcuch jest interpolowana

eval '"123 #{456.to_s} 789"' 
# => "123 456 789" 

Jednak podczas korzystania apostrofów, nie ma interpolacja, stąd # rozpoczyna komentarz, a otrzymasz

123 #{456.to_s} 789 
# => 123 

Interpolacja ciąg dzieje przed wywołaniem eval, ponieważ jest to parametr metody.

Pamiętaj też, że 456.to_s jest niepotrzebny, możesz po prostu zrobić #{456}.

+1

Zamieszczenie pojedynczych cudzysłowów w cudzysłowy daje błąd składni, ponieważ 'eval (" 123 # {456.to_s} 789 ")' jest oceniane jako '123 456 789' – Stefan

+0

co jeśli łańcuch ma # {} i cytuje w ten sposób: ciąg = '12 # {45} 78 "9" 0 ' –

3

Chciałeś:

eval('"123 #{456.to_s} 789"') 

. . . mam nadzieję, że rozumiesz, dlaczego?

Kod przekazywany do interpretera z eval jest dokładnie taki, jak zapisałeś go (w irb lub jako część pliku .rb), więc jeśli chcesz, aby eval wyświetlał wartość ciągu, ciąg, który ocenisz musi zawierają cudzysłowy, które sprawiają, że wyrażenie w nim jest String.