On Wed, Sep 05, 2007 at 04:13:20PM +0200, ry dahl wrote: > http://s3.amazonaws.com/four.livejournal/20070905/method_args-0.0.2.gem > http://s3.amazonaws.com/four.livejournal/20070905/method_args-0.0.2.zip > > Try it out and then go sit outside in the cool grass, under the warm > sun, and dream about how nice it would be to use arguments instead of > params. We could even keep params around (at no extra speed cost and > not depreciated) for those who enjoy typing. > > def show(id) > @product = Product.find(id) > render > end > > The extension is a mere 160 lines of C code. It runs quickly and it > seems to work rather well.
Yes, this is very cool. I've just posted it to ruby-talk :-) A few comments/thoughts: (1) I don't see why Method#args should raise an exception for a method which takes no arguments. Why not just return an empty array? #args? can remain but would be equivalent to #args.size > 0 (2) Would it be better to use symbols rather than strings? Ruby-1.9 now does this for method names, see http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l32 However in practice what we're talking about is local_variables. Under 1.8 this returns an array of strings, and I see no suggestion that this will change. So on second thoughts, forget this. (3) Would it be worth reflecting whether each argument is optional individually, or should we just rely on existing Method#arity? irb(main):018:0> class X irb(main):019:1> def hello(foo, bar, baz=nil, *rest) irb(main):020:2> end irb(main):021:1> end => nil irb(main):022:0> meth = x.method(:hello) => #<Method: X#hello> irb(main):023:0> meth.args => ["foo", "bar", "baz", "*rest"] irb(main):024:0> meth.arity => -3 # a bit awkward to interpret It seems that Ruby-1.9 makes life much more complicated here (ugh): http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l15 (4) For efficiency, maybe it's worth implementing the 'calling' side of this within the C extension as well. That is, take a hash, flatten the elements and send them to the receiver in the correct order. A question arises as to what happens if the hash contains keys which are not matched by the receiver. One option is to pass a hash of the left-over elements in the splat receiver, e.g. def foo(id, page=nil, *rest) puts "id=#{id.inspect}" puts "page=#{page.inspect}" puts "rest=#{rest.inspect}" end method(:foo).callvar( :id=>123, :foo=>1, :bar=>2 ) # more convenient? sendvar( :foo, :id=>123, :foo=>1, :bar=>2 ) # Result: # id=123 # page=nil # rest={:foo=>1, :bar=>2} Without a splat receiver perhaps an exception should be raised: def bar(id, page=nil) puts "id=#{id.inspect}" puts "page=#{page.inspect}" end method(:bar).callvar( :id=>123, :foo=>1, :bar=>2 ) # raises ArgumentError, no argument called :foo This _might_ be useful to application developers (i.e. if a page posts a value but you forgot to declare it in the controller method args). On the other hand it might be annoying, e.g. because you're not interested in the value of Submit buttons, hidden fields containing cookies etc. Regards, Brian. _______________________________________________ Merb-devel mailing list [email protected] http://rubyforge.org/mailman/listinfo/merb-devel
