| method args |
[Nov. 7th, 2007|01:49 am] |
Awhile ago I wrote a hack which dived deep into Ruby's parse tree to extract the names of a method's arguments. So you could do things like this require 'method_args'
class X
def hello(foo, bar)
nil
end
end
x = X.new
m = x.method(:hello)
m.args # => [:foo, :bar]I can't tell you how amazingly hackish my hack to make this work is. Exposing private data structures, blindly iterating through mysterious linked lists, etc. (Check out the code.) But it worked and I felt great having finished it.
This was all in the hope that in Merb, incoming HTTP parameters like http://a.com/blah?foo=bar&hello=world would not need to be stuffed blindly into a hash (params = {'foo' => 'bar', 'hello' => 'world' }) and then passed to the action for http://a.com/blah
def blah_action
@useful = lookup_in_database(params['foo'])
# note that params['hello'] is ignored
render 'blah.erb'
endRather one could use the syntax of Ruby to say which URL parameters it needed with method parameters! That is the action could be written this way def blah_action(foo)
@useful = lookup_in_database(foo)
# note that 'hello' isn't used and thus doesn't exist
render 'blah.erb'
endThe problem is that now the Merb team has actually decided to have this feature, but has run into a snag. What happens when a function looks like def foo(bar, baz = 1, bat = 2)
...
endand your URL looks like http://a.com/foo?bar=5&bat=6. Without knowing the default value of the middle argument baz, we cannot call the function.
After all that hacking it appears my module is still useless. Furthermore I don't have the inclination or stamina to jump into that mess again and add the feature. :( |
|
|
| Method#args 0.0.3 |
[Sep. 6th, 2007|06:47 pm] |
Method#args has a home now at http://method-args.rubyforge.org/ I released a new version too. It can be installed directly from the command line% sudo gem install method_args There are several new methods for more refined sorcery:% irb -r rubygems
>> require 'method_args'
>> class X; def foo(hello, world = 2, *blah); end; end
>> method = X.new.method :foo
=> #<Method: X#foo>
>> method.required_args
=> [:hello]
>> method.optional_args
=> [:world]
>> method.splat_arg
=> :blah
>> method.args
=> [:hello, :world, :blah]
x-posted |
|
|