Home
ryah [entries|archive|friends|userinfo]
ryah

[ website | tiny clouds ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

method args [Nov. 7th, 2007|01:49 am]
[Tags|, , ]
[Current Mood |:(]

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'
  end
Rather 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'
  end
The 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)
    ...
  end
and 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. :(
Link3 comments|Leave a comment

Method#args 0.0.3 [Sep. 6th, 2007|06:47 pm]
[Tags|, ]

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
LinkLeave a comment

method args [Sep. 4th, 2007|11:55 pm]
[Tags|, ]

Here is an extension which allows one to inspect the arguments of a method. To use it do this:
  require 'method_args'
  class X
    def hello(foo, bar)
      nil
    end
  end
  x = X.new
  meth = x.method(:hello)
  meth.argable? # => true
  meth.args # => [:foo, :bar]
  
  meth = "string".method(:split)
  meth.argable? # => false
  meth.args # => raises StandardError


http://s3.amazonaws.com/four.livejournal/20070904/method_args-0.0.1.zip
http://s3.amazonaws.com/four.livejournal/20070904/method_args-0.0.1.gem


(i feel a little like a real hacker after writing this)
LinkLeave a comment

navigation
[ viewing | most recent entries ]

Advertisement