2010-03-17 14 views
8

Bloğu bir dize olarak tanımlamak ve sonra lambda oluşturmak istiyorum. Aşağıdaki örnek işe yaramıyor. Böyle bir şey mümkün mü?Dizgiden bir ruby ​​Proc oluştur

code_string = "|x|x*2" 

l = lambda {eval(code_string)} 

l.call(3) => 6 
+1

ama neden dünyada bunu yapmak istiyoruz? “eval” neredeyse hiçbir şey yapmanın en iyi yolu değildir, verimlilik için ise başka bir şey yoktur. – Chuck

+0

Bu kesinlikle oldukça hacky görünüyor –

+0

Bazen "on-the-fly", genellikle Ruby kodu olmayan bir kaynaktan kod oluşturmanız gerekir. Transpiler uygulamak için bu tekniği kullanıyorum. –

cevap

7

Bu bunu yapar ve diğer desteklemez Sadece neden bilmiyorum

eval "lambda { " + code_string + " }" 

çalışır.

+3

Bir eval argümanı üzerinde lambda çağrılması, Proc nesnesinde "içeride" eval çağrısı olan bir Proc nesnesine neden olur. Oluşan Proc nesnesi bir argüman almaz, çünkü 'eval (code_string)' ifadesi bir argüman almaz. Proc nesnesini çağırdığınızda, code_string değerlendirir! "lambda {" + code_string + "}" dizesinin değerlendirilmesi, bir argüman bekleyen bir Proc nesnesi verir ve 2 * argümanını döndürür. – Fred

+4

Ayrıca, string interpolasyonunu kullanmak daha idiomatik (ve önyükleme için daha verimli), bu yüzden: "eval" lambda {# {code_string}} "' olacaktır. Ruby ile birkaç dizeyi '+' ile birleştirmek nadiren yapılır. – Chuck

0

eval "lambda {#{code_string}}"

kaba olmak istemem