Getting argument names and default values: doable (if hackish)

M

Mauricio Fernandez

I've written some code to get the argument names and their default values (if
any) as methods are defined; it can be found at
http://eigenclass.org/hiki.rb?method+arguments+via+introspection

It uses some tricky introspection to do it at runtime. That is, it does *not*
operate like e.g. rdoc, by parsing the source code. Instead, it actually
#require()s the code, so it will not be confused by your meta-programming,
normally.

I've made a simple script that uses that to list the public methods that will
be defined when you require a given .rb file. Its output looks like this:

$ method_args benchmark
Benchmark#benchmark (caption = "", label_width = nil, fmtstr = nil, *labels)
Benchmark#bm (label_width = 0, *labels)
Benchmark#bmbm (width = 0)
Benchmark#measure (label = "")
Benchmark#realtime ()
[...]

$ method_args rational
Rational.reduce (num, den = 1)
Rational.new! (num, den = 1)
Rational#initialize (num, den)
Rational#+ (a)
[...]

$ method_args parsedate
[...]
Date#strftime (fmt = "%F")
Date#asctime ()
Date#ctime ()
DateTime._strptime (str, fmt = "%FT%T%Z")
DateTime#strftime (fmt = "%FT%T%Z")
ParseDate#parsedate (str, comp = false)
[...]


Something to play with.
 
E

Ezra Zygmuntowicz

I've written some code to get the argument names and their default
values (if
any) as methods are defined; it can be found at
http://eigenclass.org/hiki.rb?method+arguments+via+introspection

It uses some tricky introspection to do it at runtime. That is, it
does *not*
operate like e.g. rdoc, by parsing the source code. Instead, it
actually
#require()s the code, so it will not be confused by your meta-
programming,
normally.

I've made a simple script that uses that to list the public methods
that will
be defined when you require a given .rb file. Its output looks like
this:

$ method_args benchmark
Benchmark#benchmark (caption = "", label_width = nil, fmtstr = nil,
*labels)
Benchmark#bm (label_width = 0, *labels)
Benchmark#bmbm (width = 0)
Benchmark#measure (label = "")
Benchmark#realtime ()
[...]

Hey Mauricio-

This is super cool stuff. I'm playing with it now using the version
from your site with the patch applied and it spits out all the method
names but just puts ... instead of the arguments. It does this for
anything i give it from the stdlib or my own code.


ez engine_yard $ method_args.rb benchmark
#<TypeError: allocator undefined for Binding>
Benchmark#benchmark (...)
Benchmark#bm (...)
Benchmark#bmbm (...)
Benchmark#measure (...)
Benchmark#realtime (...)
Benchmark::Job#initialize (...)
Benchmark::Job#item (...)
Benchmark::Job#report (...)

I'm on OSX Tiger latest with my own compiled ruby1.8.4. Does this
require 1.8.5 or am I doing something stupid?

Cheers-
-Ezra
 
M

Mauricio Fernandez

This is super cool stuff. I'm playing with it now using the version
from your site with the patch applied and it spits out all the method
names but just puts ... instead of the arguments. It does this for
anything i give it from the stdlib or my own code.

ez engine_yard $ method_args.rb benchmark
#<TypeError: allocator undefined for Binding>
Benchmark#benchmark (...)
Benchmark#bm (...) [...]

I'm on OSX Tiger latest with my own compiled ruby1.8.4. Does this
require 1.8.5 or am I doing something stupid?

The semantics of set_trace_func have changed somewhat in 1.8.5 [1], so it
actually requires 1.8.5. I'll try to 'backport' it to 1.8.4 tomorrow.

method_args will also print (...) for methods defined in C extensions, but
I'll probably change this to at least show the arity.

[1] it was actually a bug fix; IIRC the binding passed to the trace_func for a
(c-)return event was the caller's instead of that of the method returned from.
This is what broke Binding.of_caller/ruby-breakpoint/Rails' breakpointer.
call_stack 0.1.0, which I released last week, can overcome that.
 
M

Mauricio Fernandez

ez engine_yard $ method_args.rb benchmark
#<TypeError: allocator undefined for Binding>
Benchmark#benchmark (...)
Benchmark#bm (...) [...]
I'm on OSX Tiger latest with my own compiled ruby1.8.4. Does this
require 1.8.5 or am I doing something stupid?

Alright, it took only 1 line to make it work on both 1.8.5 and previous
versions:

$ ruby183 -v method_args-pre185.rb benchmark
ruby 1.8.3 (2005-09-21) [i686-linux]
Benchmark#benchmark (caption = "", label_width = nil, fmtstr = nil, *labels)
Benchmark#bm (label_width = 0, *labels)
Benchmark#bmbm (width = 0)
Benchmark#measure (label = "")
[...]

I've updated the code on eigenclass.org; could you give it a try?
(btw. no need to apply the patch in the comments, I had already done so)
 
E

Ezra Zygmuntowicz

ez engine_yard $ method_args.rb benchmark
#<TypeError: allocator undefined for Binding>
Benchmark#benchmark (...)
Benchmark#bm (...) [...]
I'm on OSX Tiger latest with my own compiled ruby1.8.4. Does this
require 1.8.5 or am I doing something stupid?

Alright, it took only 1 line to make it work on both 1.8.5 and
previous
versions:

$ ruby183 -v method_args-pre185.rb benchmark
ruby 1.8.3 (2005-09-21) [i686-linux]
Benchmark#benchmark (caption = "", label_width = nil, fmtstr = nil,
*labels)
Benchmark#bm (label_width = 0, *labels)
Benchmark#bmbm (width = 0)
Benchmark#measure (label = "")
[...]

I've updated the code on eigenclass.org; could you give it a try?
(btw. no need to apply the patch in the comments, I had already
done so)


Sweet! It works great now. Thanks Mauricio.

ez romper_room # ruby -v
ruby 1.8.4 (2005-12-24) [i686-darwin8.5.1]
ez romper_room # method_args.rb benchmark
#<TypeError: allocator undefined for Binding>
Benchmark#benchmark (caption = "", label_width = nil, fmtstr = nil,
*labels)
Benchmark#bm (label_width = 0, *labels)
Benchmark#bmbm (width = 0)
Benchmark#measure (label = "")
Benchmark#realtime ()
Benchmark::Job#initialize (width)
Benchmark::Job#item (label = "")
Benchmark::Job#report (label = "")


Cheers-
-Ezra
 

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

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top