Running
#!/usr/bin/env johnson
method = Ruby.eval(" lambda { |a| 10 }");
print(method(10));
f = function(){}
print(method(f));
gives
10
(eval):1: warning: multiple values for a block parameter (0 for 1)
from ./johnson/lib/johnson/spidermonkey/js_land_proxy.rb:16
10
Seems like it should show up on the Ruby side as a proc? I don't
actually need to call it, but I do need access to the js attributes of
the function object.
Hrmm. You're running into a feature. :)
Specifically, because the function is the last parameter passed, we
automagically guess that you probably intend to pass it as the block
parameter. But as you're calling a Proc, that obviously isn't very
helpful.
You'll see this behaviour go away if you add a second parameter, for
example.
I'm not sure how effectively we can solve it, really -- the other
obvious option is to require use of another method to explicitly call a
method while passing a block... but that seems to be complicating a
common case.
I suppose we could avoid the assumption in the case where the parameter
has to be there to satisfy the called method's arity... on the other
hand, maybe that would just make the behaviour even less predictable. :/
Matthew
> Specifically, because the function is the last parameter passed, we
> automagically guess that you probably intend to pass it as the block
> parameter. But as you're calling a Proc, that obviously isn't very
> helpful.
Got it.
I have analogous issues in some of my work: a little bit less common
than block passing, but still needs to have 'in band", i.e., arg list,
and "out of band", e.g., the anonymous block, parameters.
My current approach to this is to use parameters wrapped by a class
that I can detect. in this case, in theory you could do something like
my_object.method( a, b, Block(function(){}) )
Namespace issues aside, Block is a fn that returns a wrapped version
of his argument. The infrastructure then looks for trailing objects of
that type in the arg list and fits them into the proper place in the
call processing.
This is the best solution I've come up with for providing the desired
functionality without violating "least surprise".
Not that I can't live with the current solution. The workaround is no
big deal for me.