Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I marshal a lambda (Proc) in Ruby?

Joe Van Dyk asked the Ruby mailing list:

Hi,

In Ruby, I guess you can't marshal a lambda/proc object, right? Is that possible in lisp or other languages?

What I was trying to do:

l = lamda { ... }
Bj.submit "/path/to/ruby/program", :stdin => Marshal.dump(l)

So, I'm sending BackgroundJob a lambda object, which contains the context/code for what to do. But, guess that wasn't possible. I ended up marshaling a normal ruby object that contained instructions for what to do after the program ran.

Joe

like image 728
James A. Rosen Avatar asked Aug 23 '08 04:08

James A. Rosen


5 Answers

You cannot marshal a Lambda or Proc. This is because both of them are considered closures, which means they close around the memory on which they were defined and can reference it. (In order to marshal them you'd have to Marshal all of the memory they could access at the time they were created.)

As Gaius pointed out though, you can use ruby2ruby to get a hold of the string of the program. That is, you can marshal the string that represents the ruby code and then reevaluate it later.

like image 58
ryantm Avatar answered Sep 24 '22 22:09

ryantm


you could also just enter your code as a string:

code = %{
    lambda {"hello ruby code".split(" ").each{|e| puts e + "!"}}
}

then execute it with eval

eval code

which will return a ruby lamda.

using the %{} format escapes a string, but only closes on an unmatched brace. i.e. you can nest braces like this %{ [] {} } and it's still enclosed.

most text syntax highlighters don't realize this is a string, so still display regular code highlighting.

like image 36
dominic Avatar answered Sep 24 '22 22:09

dominic


If you're interested in getting a string version of Ruby code using Ruby2Ruby, you might like this thread.

like image 24
Jonathan Tran Avatar answered Sep 22 '22 22:09

Jonathan Tran


Try ruby2ruby

like image 3
James A. Rosen Avatar answered Sep 23 '22 22:09

James A. Rosen


I've found proc_to_ast to do the best job: https://github.com/joker1007/proc_to_ast.

Works for sure in ruby 2+, and I've created a PR for ruby 1.9.3+ compatibility(https://github.com/joker1007/proc_to_ast/pull/3)

like image 1
Peter P. Avatar answered Sep 21 '22 22:09

Peter P.