Derek Ekins
Derek Ekins

Reputation: 11391

Printing the source code of a Ruby block

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?

Upvotes: 15

Views: 6010

Answers (6)

pixelearth
pixelearth

Reputation: 14610

In ruby 2.7, using the method_source gem (pry depends on it)

Set.instance_method(:merge).source.display
# =>
def merge(enum)
  if enum.instance_of?(self.class)
    @hash.update(enum.instance_variable_get(:@hash))
  else
    do_with_enum(enum) { |o| add(o) }
  end

  self
end

The repo says it works for procs, but I haven't tested it.

Upvotes: 2

surgentt
surgentt

Reputation: 406

In Ruby 2.5 the following works

puts block.source

Upvotes: 1

Nick B
Nick B

Reputation: 7689

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)

Upvotes: 6

Seamus Abshere
Seamus Abshere

Reputation: 8516

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.

Upvotes: 4

Evangenieur
Evangenieur

Reputation: 21

In Ruby 1.9, you can try this gem which extract the code from source file.

https://github.com/ngty/sourcify

Upvotes: 2

Corban Brook
Corban Brook

Reputation: 21378

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.

Upvotes: 8

Related Questions