Ruby reflection - get method definition as a string

L

Laup-Dawg

Hi Folks - I am running some ruby tests and would like to print out
the actual test to the console or store it to a file. The tests are
written as classes with a setup, run, and teardown method.
So here's my question: is there a way to get the class definition or
method definitions as a "string", so that I can print it out (to a
file or console)?
I know ruby supports a lot of reflection (like .methods
or .constants), but I'm not seeing how to do this.
Thanks!
 
A

Anurag Priyam

Hi Folks - I am running some ruby tests and would like to print out
the actual test to the console or store it to a file. =A0The tests are
written as classes with a setup, run, and teardown method.
So here's my question: is there a way to get the class definition or
method definitions as a "string", so that I can print it out (to a
file or console)?
I know ruby supports a lot of reflection (like .methods
or .constants), but I'm not seeing how to do this.

A very non-elegant, trivial way using Ruby's DATA stream ;) :

# test.rb
def foo
puts "hi"
end

flag =3D nil
DATA.tap{|x| x.rewind}.readlines.each do |line|
flag =3D true if line =3D~ /^def/
puts line if flag
flag =3D false if line =3D~ /^end/
end
__END__

$ ruby test.rb
def foo
puts "hi"
end

Obviously you will have to come up with better heuristics to determine
the end of a method.

--=20
Anurag Priyam
http://about.me/yeban/
 
F

Florian Gilcher

=20
A very non-elegant, trivial way using Ruby's DATA stream ;) :
=20
# test.rb
def foo
puts "hi"
end
=20
flag =3D nil
DATA.tap{|x| x.rewind}.readlines.each do |line|
flag =3D true if line =3D~ /^def/
puts line if flag
flag =3D false if line =3D~ /^end/
end
__END__
=20
$ ruby test.rb
def foo
puts "hi"
end
=20
Obviously you will have to come up with better heuristics to determine
the end of a method.
=20

In Ruby 1.9, you can retrieve the place where the method was defined =
using #source_location:

def foo

end
=20
method:)foo).source_location #=3D> ["file.rb", 1]

The same goes for procs:

def foo(&block)
puts block.source_location.inspect
end

foo do

end #=3D> ["file.rb", 5]

Regards,
Florian
 
E

Eric Christopherson

Cool, I didn't realize you access the source file using tap and rewind.
$ ruby test.rb
def foo
=A0puts "hi"
end

Obviously you will have to come up with better heuristics to determine
the end of a method.

In Ruby 1.9, you can retrieve the place where the method was defined usin= g #source_location:

=A0def foo

=A0end

=A0method:)foo).source_location #=3D> ["file.rb", 1]

The same goes for procs:

=A0def foo(&block)
=A0 =A0puts block.source_location.inspect
=A0end

=A0foo do

=A0end #=3D> ["file.rb", 5]

I just discovered #source_location a week or so ago, but I immediately
wondered if there was a way to discern the end of a block or method. I
never found one. Might one be added in a future Ruby?
 
J

James M. Lawrence

Adam Lauper wrote in post #982302:
Hi Folks - I am running some ruby tests and would like to print out
the actual test to the console or store it to a file. The tests are
written as classes with a setup, run, and teardown method.
So here's my question: is there a way to get the class definition or
method definitions as a "string", so that I can print it out (to a
file or console)?
I know ruby supports a lot of reflection (like .methods
or .constants), but I'm not seeing how to do this.
Thanks!

I just released a gem which gives access to the source code of methods
and procs (http://github.com/quix/live_ast). See the "to_ruby" section
of the readme. Since the string returned by to_ruby is a parsed/unparsed
version of your code, it probably won't match the original source (and
comments will be gone), but it may suffice for your needs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top