Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing the source code of a Ruby block

Tags:

ruby

I have a method that takes a block.

Obviously I don't know what is going to be passed in and for bizarre reasons that I won't go into here I want to print the contents of the block.

Is there a way to do this?

like image 239
Derek Ekins Avatar asked Nov 04 '09 16:11

Derek Ekins


3 Answers

You can do this with Ruby2Ruby which implements a to_ruby method.

require 'rubygems'
require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'

def meth &block
  puts block.to_ruby
end

meth { some code }

will output:

"proc { some(code) }"

I would also check out this awesome talk by Chris Wanstrath of Github http://goruco2008.confreaks.com/03_wanstrath.html He shows some interesting ruby2ruby and parsetree usage examples.

like image 160
Corban Brook Avatar answered Sep 19 '22 15:09

Corban Brook


In Ruby 1.9+ (tested with 2.1.2), you can use https://github.com/banister/method_source

Print out the source via block#source:

#! /usr/bin/ruby
require 'rubygems'
require 'method_source'

def wait &block
  puts "Running the following code: #{block.source}"
  puts "Result: #{yield}"
  puts "Done"
end

def run!
  x = 6
  wait { x == 5 }
  wait { x == 6 }
end

run!

Note that in order for the source to be read you need to use a file and execute the file (testing it out from irb will result in the following error: MethodSource::SourceNotFoundError: Could not load source for : No such file or directory @ rb_sysopen - (irb)

like image 5
Nick B Avatar answered Sep 21 '22 15:09

Nick B


Building on Evangenieur's answer, here's Corban's answer if you had Ruby 1.9:

# Works with Ruby 1.9
require 'sourcify'

def meth &block
  # Note it's to_source, not to_ruby
  puts block.to_source
end

meth { some code }

My company uses this to display the Ruby code used to make carbon calculations... we used ParseTree with Ruby 1.8 and now sourcify with Ruby 1.9.

like image 4
Seamus Abshere Avatar answered Sep 22 '22 15:09

Seamus Abshere