2010-03-17 15 views
8

Ich möchte den Block als Zeichenfolge definieren, erstellen Sie dann das Lambda. Das folgende Beispiel funktioniert nicht. Ist so etwas möglich?Erstellen Sie einen Ruby Proc aus einer Zeichenfolge

code_string = "|x|x*2" 

l = lambda {eval(code_string)} 

l.call(3) => 6 
+1

meine ich nicht unhöflich klingen, aber warum in der Welt tun Sie dies tun wollen? 'eval' ist fast nie der beste Weg etwas zu tun, nur um der Effizienz willen. – Chuck

+0

Dies scheint definitiv ziemlich hacky –

+0

Manchmal müssen Sie Code "on-the-fly" generieren, oft aus einer Quelle, die nicht Ruby-Code ist. Ich benutze diese Technik, um einen Transpiler zu implementieren. –

Antwort

7

Dies funktioniert

eval "lambda { " + code_string + " }" 

Ich weiß nicht genau, warum dieses tut und das andere nicht.

+3

Der Aufruf von Lambda für ein Eval-Argument führt zu einem Proc-Objekt, bei dem der Eval-Aufruf das Proc-Objekt "innerhalb" hat. Das resultierende Proc-Objekt nimmt kein Argument, da der Ausdruck "eval (code_string)" kein Argument benötigt. Wenn Sie das Proc-Objekt aufrufen, wird der code_string aufgerufen! Das Eval der Zeichenfolge "Lambda {" + Codezeichenfolge + "}" gibt ein Proc-Objekt, das ein Argument erwartet, und gibt 2 * Argument zurück. – Fred

+4

Außerdem ist es idiomatischer (und effizienter zu booten), String-Interpolation zu verwenden, also wäre es: "eval" lambda {# {code_string}} "'. Die Verkettung mehrerer Strings mit '+' wird in Ruby selten durchgeführt. – Chuck

0

eval "lambda {#{code_string}}"

Verwandte Themen