2010-01-17 60 views
17

拿這個例子:紅寶石塊字符串,而不是執行

write_as_string { puts 'x' } 

話,我希望能夠做到

def write_as_string(&block) 
    puts block.to_s 
end 

當我執行此,我想輸出是:

"puts 'x'" 

我希望能夠接收塊並獲得該塊的實際代碼而不是執行它。動機:創建一個DSL,我希望模擬可以轉化爲其他一些方法調用,從調用代碼中隱藏起來 - 使用現有的對象和方法而不用猴子修補它們。

任何想法都會很棒!

感謝

回答

1

你想要ruby2ruby gem,這很好地做到這一點。不幸的是,要分析一塊這塊寶石取決於ParseTree,它是unsupported in Ruby 1.9

+0

這似乎很酷。但是,考慮到下面的例子,我需要以某種方式將定義的塊作爲一個字符串。我怎麼能這樣做? 紅寶石= 「DEF一個\ n看跌期權 'A' \ NEND \ n \ NDEF b \ NA \ NEND」 解析器= RubyParser.new ruby​​2ruby = Ruby2Ruby.new SEXP = parser.process(紅寶石) 或者有我錯過了什麼? – 2010-01-17 21:42:15

+0

如果你不關心1.9兼容性,我會推薦@ mletterle的答案。 – austinfromboston 2010-01-20 04:01:05

3

重複: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\") }" 
18

如果你在Ruby 1.9的,你可以使用sourcify寶石。它提供了Proc#to_source,就像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 

我張貼在我公司的博客大約ParseTree and Ruby 1.9

+0

我有幸爲Ruby 2.1.2提供了source_method gem(pry包含作爲依賴關係,所以在我需要的測試基礎結構中已經可用)。我在這裏有詳細的答案:http://stackoverflow.com/questions/1675053/printing-the-source-code-of-a-ruby-block/36654421#36654421 – Nick 2016-04-15 18:30:07