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

Reply via email to