Ruby块转换为字符串,而不是执行

Ruby块转换为字符串,而不是执行,ruby,Ruby,举个例子: write_as_string { puts 'x' } 然后我想能够做到 def write_as_string(&block) puts block.to_s end 执行此操作时,我希望输出为: "puts 'x'" 我希望能够接收块并获取块的实际代码,而不是执行它 动机:创建一个DSL,我想将模拟转换成许多其他方法调用,隐藏在调用代码中-使用现有的对象和方法,而不使用猴子补丁 任何关于这方面的想法都会很棒 谢谢 Ben你想要的是一个能很好地实现这一点的。不幸

举个例子:

write_as_string { puts 'x' }
然后我想能够做到

def write_as_string(&block)
  puts block.to_s
end
执行此操作时,我希望输出为:

"puts 'x'"
我希望能够接收块并获取块的实际代码,而不是执行它

动机:创建一个DSL,我想将模拟转换成许多其他方法调用,隐藏在调用代码中-使用现有的对象和方法,而不使用猴子补丁

任何关于这方面的想法都会很棒

谢谢

Ben

你想要的是一个能很好地实现这一点的。不幸的是,要分析一个块,这个gem依赖于ParseTree,它是重复的:

然后

导致

irb(main):008:0> block_as_string {puts 'x'}
=> "proc { puts(\"x\") }"

如果您使用的是Ruby 1.9,那么可以使用sourcify gem。它提供Proc#to_源代码,类似于ParseTree的Proc#to_ruby

使用sourcify时,如果源代码中有嵌套的进程,则可能需要使用:attached_to选项来帮助它:

## (Works in Ruby 1.8) Using ParseTree (with parse_tree_extensions)
block.to_ruby
## (Works in Ruby 1.9) Using sourcify
block.to_source
## Try this if you get Sourcify::NoMatchingProcError or Sourcify::MultipleMatchingProcsPerLineError
block.to_source :attached_to => :name_of_block_in_source_code

我在公司的博客上发布了这篇文章。

这看起来很酷。但是给出下面的示例,我需要以某种方式将定义的块作为字符串。我怎么能这样做?ruby=“def a\n puts'a'\nend\n\ndef b\n a\nend”parser=RubyParser.new ruby2ruby=ruby2ruby.new sexp=parser.process(ruby)还是我遗漏了什么?如果你不关心1.9的兼容性,我会推荐@mlettele的答案。我在ruby 2.1.2的源方法gem方面很幸运(pry将其作为一个依赖项包含在我们的测试基础架构中,我需要它)。我在这里有一个详细的答案:
irb(main):008:0> block_as_string {puts 'x'}
=> "proc { puts(\"x\") }"
## (Works in Ruby 1.8) Using ParseTree (with parse_tree_extensions)
block.to_ruby
## (Works in Ruby 1.9) Using sourcify
block.to_source
## Try this if you get Sourcify::NoMatchingProcError or Sourcify::MultipleMatchingProcsPerLineError
block.to_source :attached_to => :name_of_block_in_source_code