【问题标题】:Ruby block to string instead of executing [duplicate]Ruby块到字符串而不是执行[重复]
【发布时间】:2020-08-21 23:34:20
【问题描述】:

举个例子:

write_as_string { puts 'x' }

然后我希望能够做到

def write_as_string(&block)
  puts block.to_s
end

当我执行这个时,我希望输出是:

"puts 'x'"

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

动机:创建 DSL,我想将模拟转换为许多其他方法调用,对调用代码隐藏 - 使用现有的对象和方法而不用猴子修补它们。

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

谢谢

【问题讨论】:

    标签: ruby


    【解决方案1】:

    如果您使用的是 Ruby 1.9,则可以使用 sourcify gem。它提供了 Proc#to_source,类似于 ParseTree 的 Proc#to_ruby。

    使用 sourcify 时,如果您的源代码中有嵌套的 proc,您可能需要使用 :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
    

    我在公司的博客中发布了关于ParseTree and Ruby 1.9 的信息。

    【讨论】:

    【解决方案2】:

    重复:Printing the source code of a Ruby block

    sudo gem install ParseTree
    sudo gem install ruby2ruby
    

    然后

    require 'rubygems'
    require 'parse_tree'
    require 'parse_tree_extensions'
    require 'ruby2ruby'
    
    def block_as_string &block
        block.to_ruby
    end
    

    结果

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

    【讨论】:

      【解决方案3】:

      您想要ruby2ruby gem,它可以很好地做到这一点。不幸的是,要分析一个块,这个 gem 依赖于 ParseTree,它是 unsupported in Ruby 1.9

      【讨论】:

      • 这看起来很酷。但是鉴于以下示例,我需要以某种方式将定义的块作为字符串获取。我怎么能这样做? ruby = "def a\n puts 'A'\nend\n\ndef b\n a\nend" parser = RubyParser.new ruby​​2ruby = Ruby2Ruby.new sexp = parser.process(ruby) 还是我错过了什么?
      • 如果您不关心 1.9 的兼容性,我会推荐 @mletterle 的答案。
      猜你喜欢
      • 2017-10-11
      • 1970-01-01
      • 2020-08-17
      • 2011-03-22
      • 2023-03-28
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多