Ruby block to string instead of executing [duplicate]
Take this example:
write_as_string { puts 'x' }
I then want to be able to do
def write_as_string(&block)
puts block.to_s
end
When I execute this, I want the output to be:
"puts 'x'"
I want to be able to receive the block and get the actual code for the block instead of executing it.
Motivation: Creating a DSL, I want to the mock to be converted into a number of other method calls, hidden from the calling code - using existing objects and methods without monkey patching them.
Any ideas on this would be great!
Thanks
Ben
If you're on Ruby 1.9, you can use the sourcify gem. It provides Proc#to_source, which is like ParseTree's Proc#to_ruby.
When using sourcify, if you have nested procs in your source code, you might have to help it along with the :attached_to option:
## (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
I posted about ParseTree and Ruby 1.9 in my company's blog.
Duplicate: Printing the source code of a Ruby block
sudo gem install ParseTree
sudo gem install ruby2ruby
then
require 'rubygems'
require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'
def block_as_string &block
block.to_ruby
end
results in
irb(main):008:0> block_as_string {puts 'x'}
=> "proc { puts(\"x\") }"
You want the ruby2ruby gem, which does this nicely. Unfortunately, to analyze a block this gem depends on ParseTree, which is unsupported in Ruby 1.9.
精彩评论