Parsing Ruby to get info about method signatures?



  • 1. gems and test dependencies
    Hi all, I've noticed that a few packages require certain third party packages, but only for the test suite, e.g. net-sftp requires flexmock and I require sys-proctable for the win32-process test suite. Any chance of adding something like "test_dependency"? Or does something like that exist and I didn't see it? Regards, Dan

Parsing Ruby to get info about method signatures?

Postby Lyle Johnson » Sat, 21 Oct 2006 06:16:54 GMT

I'm interested in parsing some Ruby code for the purpose of extracting
information about the method signatures (including argument names and
default argument values). For example, if I had a method like:

    def foo(a, b=2, c=3)

I'd like to be able to programmatically determine that I have a method
named "foo", with arguments "a", "b" and "c", with defaults of 2 and 3
for the latter two arguments. (I will use that information about the
method signatures to generate some additional code.)

Does anyone have any experience with this? I looked at the XML
generator for RDoc, but its output doesn't appear to provide this kind
of information. Ryan's ParseTree library may do the trick, or worst
case, I could write some kind of custom parsing tool myself. Just
wanted to see if anyone has any thoughts on this.

Re: Parsing Ruby to get info about method signatures?

Postby Mauricio Fernandez » Sat, 21 Oct 2006 07:29:58 GMT


 http://www.**--****.com/ +arguments+via+introspection

$ ruby method_args.rb csv
CSV::Cell#initialize (data = "", is_null = false)
CSV::Cell#data () (path, mode, fs = nil, rs = nil)
CSV.foreach (path, rs = nil) (path, length = nil, offset = nil)
CSV.readlines (path, rs = nil)
CSV.generate (path, fs = nil, rs = nil)
CSV.parse (str_or_readable, fs = nil, rs = nil)
CSV.parse_line (src, fs = nil, rs = nil)
CSV.generate_line (row, fs = nil, rs = nil)
CSV.parse_row (src, idx, out_dev, fs = nil, rs = nil)
CSV.generate_row (src, cells, out_dev, fs = nil, rs = nil)
CSV::Reader.parse (str_or_readable, fs = ",", rs = nil)
CSV::Reader.create (str_or_readable, fs = ",", rs = nil)
CSV::Reader#each ()
CSV::Reader#shift ()
CSV::Reader#close ()
CSV::Reader#initialize (dev)
CSV::StringReader#initialize (string, fs = ",", rs = nil)

Mauricio Fernandez  -    http://www.**--****.com/    -  singular Ruby

Re: Parsing Ruby to get info about method signatures?

Postby Lyle Johnson » Sun, 22 Oct 2006 02:25:45 GMT

Thanks, Mauricio! I will check this out too.

Similar Threads:

1.Beginner 'How-to' Question on getting Array info

2.[proto-rcr] Blocks: default arguments and method signatures

I thought I'd post these ideas here, since last time I wrote up an RCR 
and then got told that the issue had already been addressed in plans for 
Ruby 2. Also, some ideas I'm pretty happy with, some are quite 
radical/provocative. Hopefully those latter bits are somewhat 
independent, which ones do you like? (if any ;)
So please let me know if I'm missing something, or this could be done 

1) Default arguments for &block
Often a method performs some simple reasonably useful behaviour if no 
block is given, otherwise it lets the block do something more useful. 
For example:

def transform_values(array)
	out=[] unless block_given?
	array.each { |value|
		# calculations...
		if block_given?
			yield value,newvalue
			out<< newvalue

I propose &block could take a default argument, probably of the form
&block={|x| foo}, but I could live with &block=proc {|x| foo}.
block_given? would return *false* if the default value was used (I'm 
flexible on this bit).
The default block would be scoped *inside* the method.
That example would become:

def transform_values(array) &block={|val,newval| out<< newval}
	out=[] unless block_given?
	array.each { |value|
		yield value,newvalue

2) Taking anonymous block parameter, making it part of the signature
Two issues:
   	a) If block default values are adopted, then giving the block a
	     name might sometimes seem silly, as the name's never used.
	     See the above example, "block" is never referenced.
	b) No way to specify taking a block as part of method signature.
	     Descrptive signatures are good:
	     * See syntax in auto-docs/code without reading whole thing
	     * See syntax in auto-docs/code when there's no comments		
	     * Flag errors at start of method, and on every invocation.	

Proposal: allow "&" in place of "&block":
def foo &	(or maybe: def foo &!)
	As soon as the method is called, raises an error if no block is
	given (similar to wrong number of args)
def foo &?	(or maybe: def foo &)
	No change from current behaviour of def foo, but denotes that
	this method can take a block and might use it if given.
def foo &block! or
def foo &!block	or
replace current meaning(!) of: def foo &block
	This method is required to take a block, not passing a block
	raises an error.
def foo &block or
def foo &block? or
def foo &?block, etc
	Current meaning of &block.

My preferred syntax in a throw-everything-away-for-Ruby2 scenario:
		Named block		Anonymous block
Disallowed	def foo			def foo
Optional	def foo &block?		def foo &?
Defaulted	def foo &block={}	def foo &={}
Compulsory	def foo &block		def foo &

My preferred syntax in a backwards-compatible scenario:
		Named block		Anonymous block
Disallowed	-			-
Optional	def foo &block		def foo &?
Defaulted	def foo &block={}	def foo &={}
Compulsory	def foo &block!		def foo &!


3.Documenting a class interface when there are no types in the method signature

I've recently started using Ruby, coming from a C++/Java background.

And while there where some idiosyncracies, by and large I was able to be
very productive very quickly.

The application has evolved from a simple script (in the sense that
everything "looks global") to something a bit more complex, with
refactorings towards using objects, a "Test-First-After-The-Fact" approach
:-), and to factoring out library-like elements.

Now, I'm aware that there's always a discussion about strong vs. weak,
static vs. dynamic. The last time I had an opinion about it I had no good
answer to the claim that unit-tests lessen the need for static type

Now that I have gulped down the basics of ruby, I'm starting writing unit
tests, from the point of view of "what would a user of this class expect".
And I'm running into what seems to be a fundamental question, and my
googling so far hasn't turned up any satisfactory answer:
When I define a method in a class, let's say initialize(categories, data)
for the sake of argument: In Java etc. I can see from the method definition
that categories is an ordered set, and data is a Map (and if that info is
not sufficient, javadoc can be used to explain in more detail what is
expected, but I'll leave that out for the moment, it's not really key to the
Of course the first step would be to find a good name (at the very least
"data" is a bit too generic). But what next? How does someone who writes an
API communicate that it makes no sense to send "1" to the categories.
Apparently the unit tests and/or dbc encompass the specification, but does
rdoc or some tool extract any information from them?

Am I the first person to run in this problem? If not, what are other
people's solutions? Do you just look at the source code of any library you

I'm asking this from both points of view:

Many times I have run into some library where I was simply asking myself
"what exactly do I have to put into these parameters to get the method to do
what I want?" More specifically, I had this problem in parts of the REXML

And from the other perspective, what is the Ruby Way (tm) to document
methods to users of your API/framework (or simply your class)?

4.getting info about attached displays

5.Problem with getting info from several websites

6. Getting test method names when getting output

7. FastRI 0.3.0: standalone mode (qri, DRb not needed), additional search methods, extended class info

8. Passing info to classes and methods

Return to ruby


Who is online

Users browsing this forum: No registered users and 8 guest