action-args: Impossible to keep with Ruby 1.9 and alternative VMs

6 views
Skip to first unread message

Nicos Gollan

unread,
Apr 20, 2011, 7:42:41 AM4/20/11
to merb
merb-action-args provides out-of-order defaults as a feature.

To quote the README:

===========================
## Out of order defaults

class Foo < Merb::Controller
def bar(one, two = "dos", three = "tres")
"#{one} #{two} #{three}"
end
end

The interesting thing here is that hitting `"/foo/bar?
one=uno&three=three"` will call
`foo("uno", "dos", "three")`. In other words, the defaults can be in
any order, and
merb-action-args will figure out where to fill in the holes.
===========================

This is not possible with at least MRI =>1.9.2 and Rubinius, since
those VMs do not allow to retrieve parameter defaults. (Yehuda was
pretty much the initiator of Method#parameters in MRI, but they could
not find a good generic way to deliver defaults that way.)
Additionally, the Ruby language itself does not provide features
required to re-order parameters, or omit parameters when calling a
method.

Currently, action-args is broken on those VMs since it provides nil
default values, so in the example above. the called action would
actually be Foo#bar("uno", nil, "three").

The alternatives I see are:

* drop the out-of-order capability.
* require some explicit support in the application, e.g., by
replacing nil values or another sentinel with the defaults again, or
* switch to a "magic" action definition altogether.

I do not like the magic version, since it would entirely break the
idea of just defining normal methods for controller actions. Neither
do I think that completely dropping the capability would be warranted.

The nil sentinel approach would mean application writers would have to
do something like:

def show(id, xss_content = nil)
# either assuming nil (or that no values reaching the controller
coalesce)
xss_content ||= "<script type='text/
javascript'>mail_password('ev...@example.org')</script>"

# or, with another sentinel and a convenience method:
parameter_default(:xss_content, "...")

# ...
end

Specifying defaults would still be useful for action-args to recognise
optional parameters and at least keep it raising BadRequest when
parameters are missing.

For now, I will keep filling in nil for missing defaults, since that's
what git master has been doing for quite some time now. If no
objections or better alternatives come up, I will use one or another
sentinel approach, and integrate the whole thing into merb-core.

Eager for opinions and some discussion,
Nicos
Reply all
Reply to author
Forward
0 new messages