Joe Van Dyk 询问了Ruby邮件列表

嗨,

在Ruby中,我猜你不能编组一个lambda / proc对象,对吗? 在lisp或其他语言中这可能吗?

我想做什么:

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

所以,我正在向BackgroundJob发送一个lambda对象,该对象包含要执行的操作的上下文/代码。 但是,猜测这是不可能的。 我最终编组了一个普通的ruby对象,其中包含程序运行后要执行的操作的说明。

===============>>#1 票数:21 已采纳

你不能编组Lambda或Proc。 这是因为它们都被认为是闭包,这意味着它们靠近定义它们的内存并且可以引用它。 (为了编组它们,你必须将它们在创建时可以访问的所有内存编组。)

正如Gaius指出的那样,你可以使用ruby2ruby来获取程序的字符串。 也就是说,您可以封送代表ruby代码的字符串,然后再重新评估它。

===============>>#2 票数:11

你也可以输入你的代码作为字符串:

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

然后用eval执行它

eval code

这将返回红宝石lamda。

使用%{}格式转义字符串,但仅在不匹配的大括号上关闭。 即你可以像这个%{ [] {} }那样嵌套大括号,它仍然是封闭的。

大多数文本语法荧光笔没有意识到这是一个字符串,所以仍然显示常规代码突出显示。

===============>>#3 票数:4

如果您对使用Ruby2Ruby获取Ruby代码的字符串版本感兴趣,您可能会喜欢这个主题

===============>>#4 票数:3

试试ruby2ruby

===============>>#5 票数:1

我发现proc_to_ast做得最好: https//github.com/joker1007/proc_to_ast

确实在ruby 2+中工作,我为ruby 1.9.3+兼容性创建了一个PR( https://github.com/joker1007/proc_to_ast/pull/3

===============>>#6 票数:0

如果将proc定义到文件中,U可以获取proc的文件位置然后序列化它,然后在反序列化后使用该位置再次返回proc

proc_location_array = proc.source_location

反序列化后:

file_name = proc_location_array [0]

line_number = proc_location_array [1]

proc_line_code = IO.readlines(file_name)[line_number - 1]

proc_hash_string = proc_line_code [proc_line_code.index(“{”).. proc_line_code.length]

proc = eval(“lambda#{proc_hash_string}”)

===============>>#7 票数:0

曾几何时,这可能是使用ruby-internal gem( https://github.com/cout/ruby-internal ),例如:

p = proc { 1 + 1 }    #=> #<Proc>
s = Marshal.dump(p)   #=> #<String>
u = Marshal.load(s)   #=> #<UnboundProc>
p2 = u.bind(binding)  #=> #<Proc>
p2.call()             #=> 2

有一些警告,但它已经很多年了,我不记得细节了。 作为一个例子,我不确定如果一个变量是它被转储的绑定中的dynvar和绑定中的一个本地被重新绑定,会发生什么。 序列化AST(在MRI上)或字节码(在YARV上)是非平凡的。

以上代码适用于YARV(最高1.9.3)和MRI(最高1.8.7)。 没有理由不能通过少量努力使它在Ruby 2.x上运行。

  ask by James A. Rosen translate from so

未解决问题?本站智能推荐:

4回复

你如何串行化/序列化Ruby代码?

我希望能够在我的Ruby代码中编写lambda / Proc,将其序列化以便我可以将其写入磁盘,然后再执行lambda。 有点像...... 后来,在另一个Ruby解释器的运行中,我想能够说... Marshal.dump不适用于Procs。 我知道Perl有Data ::
5回复

Ruby:将proc转换为lambda?

是否有可能将proc风味的Proc转换为lambda风味的Proc? 有点惊讶,这不起作用,至少在1.9.2:
3回复

Ruby - lambda vs. Proc.new [复制]

可能重复: Ruby中的proc和lambda有什么区别? 运行这个Ruby代码时: 我得到的结果如下: 至于func_two , 第一个 return的值是哪里,即123 ? 谢谢。
2回复

另一个proc与lambda讨论

我以为,当您在某个方法内调用proc时,该proc的返回值将触发从称为proc的out块上下文返回的值。 当我调用test(a_block)我觉得不应执行puts "after the block"因为proc中有返回值。 进一步... test(a_block)和test(b_block)
5回复

Ruby块,proc和instance_eval

我最近尝试做类似的事情: 给出错误: TypeError:无法将Proc转换为String 但这有效: 使用此方法的进一步介绍: 产生相同的Proc to String错误。 所以...我对块的理解是它们只是proc。 但是拥有&符号显然
1回复

Ruby Proc:从类B中调用A类中的方法,并使用B类的'方法'

我不确定这是否实际上可行,但是我无法在任何地方找到明确的答案。 另外,我发现很难仅凭“搜索字词”来定义我的问题。 因此,很抱歉,如果在其他地方已经回答了这个问题,我找不到它。 我想知道的是,是否可以创建一个Proc,它包含一个未在定义Proc的位置定义的方法。 然后我想将该实例放在另
2回复

我们如何在不同的Ruby类之间复制单例方法?

我试图用一个方法定义一个类,一个缺少这些方法的类,然后允许后一个类的对象从前一个类的实例中“学习”这些方法。 这是我的尝试(Ruby 1.9.2) - 当我尝试在lambda绑定中更改'self'的值时,它会中断(在行评论“BREAKS!”)。 如果你能弄清楚如何解决这个问题 - 我
1回复

proc函数对方法有什么好处

我在Project Euler上解决了一些问题,并且我提到我总是在proc函数中包含短方法。 我问自己“ 为什么? ”。 答案是“ 我不知道。也许是因为它很短? ”。 那么proc函数对普通方法有什么好处,除了它们很短:)
7回复

在Ruby块中使用'return'

我正在尝试将Ruby 1.9.1用于嵌入式脚本语言,以便“最终用户”代码在Ruby块中编写。 这个问题的一个问题是我希望用户能够在块中使用'return'关键字,因此他们不需要担心隐式返回值。 考虑到这一点,这是我希望能够做到的事情: 如果我在上面的例子中使用'return',我会得
1回复

ruby块中'return'关键字的行为

有人可以解释以下行为 我知道Procs(这是什么块)应该在它们被调用的范围内返回。 (与lambdas不同)考虑到这一点,测试中的两个调用都不应该返回“块结束”吗? 此测试传递'ruby 1.8.7(2009-06-12 patchlevel 174)[universal-dar