C
Charles Oliver Nutter
Not very quackish.
Neither are case/when statements like this:
case obj
when String ...
when Regexp ...
end
But sometimes that's what you need to do.
- Charlie
Not very quackish.
Adam said:Not very quackish.
Eric said:Whenever the overloading topic comes up, I wonder about what the
future holds regarding true named arguments. Does anyone know?
Anyway, I wonder if there has been any talk between MacRuby and the
other Ruby implementations on getting this sort of keyed arguments
standardized.
2011/1/29 J=C3=B6rg W Mittag said:AFAIK, Laurent Sansonetti did consult with matz to make sure that
MacRuby's extensions would be forward compatible.
So, while there does not exist a design, let alone an implementation
of named arguments for Ruby 2.0, it seems to be clear that whatever
design they come up with, will have to be compatible with MacRuby.
Specifically, MacRuby has an extension to the usual hash parameters
that seems pretty complicated to me, but allows it to interact fairly
painlessly with Objective-C*. It basically allows you to define a
method with named parameters. It's bewildering because a method
invocation like "person.setFirstName('Gloria', { :lastName=>'Alvarez'
})" actually calls a *different* method from
"person.setFirstName('Gloria', lastName: 'Alvarez')" (the former is
the regular Ruby hash argument type; the latter uses the
MacRuby-specific keyed arguments. If no keyed-argument version of a
method exists, it will just translate it into a hash-argument form.)
thod overloading -- that unless done very carefully indeed, it makes the co=So far I don't believe I've heard anyone make the obvious case against me=
duck typing. =A0Duck typing rules out method overloading, because paramete=Or, indeed, the practical case - at the very heart of Ruby is the idea of=
of duck typing. Duck typing rules out method overloading, because =Or, indeed, the practical case - at the very heart of Ruby is the idea =
Charles said:Laurent can correct me if I'm wrong, but I don't think ObjC's syntax
qualifies as true named arguments.
In MacRuby/ObjC, a method call like
foo(bar:1, baz:2)
Is just a way of saying something like
foo_with_bar_with_baz(1, 2)
The method name and the argument names actually resolve to different
method bodies internally. In addition, the order is absolutely
crucial. The following two calls are not the same and will not end up
in the same target method:
foo(bar: 1, baz: 2)
foo(baz: 2, bar: 1)
he number of parameters but not their type.I think the original poster provided an example of overloading based on t=
Ruby because the arity still has to be determined (in some cases) dynamica=Even restricting yourself to overloading by arity is a bit problematic in=
args =3D [1,2]
foo(*args) =A0 =A0 =A0# two arguments
args << 3
foo(*args) =A0 =A0 =A0# three arguments
Actually, arity of callsite is always calculated =C2=A0in Ruby to know if
you should throw an ArgumentError (3 for 0 specified sort of errors)
against the method you are calling. =C2=A0It seems like overloading based
on arity is not such a bad idea to me based on some of the common
arity parsing idioms people do by hand in the first few lines of their
methods. =C2=A0What implementing arity-based overloads would do is get ri= d
of most of this code we put at the top of methods and perform that
logic in the Ruby implementation itself (in MRI in C vs in Ruby).
Stylistically, I think the biggest issue is not realizing there are n
overloads and then implementing less than n overloads in an overridden
class.
Seems like you can get pretty far though with just a little
meta-programming with no special language support:snip
That=E2=80=99s neat. Thanks!
-- =
Posted via http://www.ruby-forum.com/.=
in Ruby because the arity still has to be determined (in some cases) dynam=
ically:ed to calculate arity but instead was pointing out that you can't just calc=Maybe I'm overlooking something but I wasn't suggesting that you don't ne=
ulate it at parse time but sometimes need to calculate it at call time.n opportunities for some call sites but not for every call site.foo(1,2) =A0 =A0 # the call arity can be computed at parse time
foo(*a) =A0 =A0 =A0# the call arity must be computed at call time
So in an 'overload-based-on-arity' scheme there might be some optimizatio=
Yeah, that is certainly true in the general sense even in existing
Ruby semantics. In your first example, we know that it is always a
two-arg call (at parse time) so we can go through a two-arity call
path and not 'box' the call parameters into an array. In the second
case we might be able to know arity at parse time if we know 'a' is a
literal array. If we don't then the optimizations we can do get
more limited.
You are correct that adding arity to the mix would make the
optimizations more complex, but I think it depends on the case and
what you get by supporting it. For example, in the second case if we
made our callsite cache lookup the methods foo and cache all of them
at the site, then dispatch to the appropriate one, we would have quite
a bit more complicated callsite cache (since we would need to
invalidate it if any arity version changed), but this would dispatch
much faster than doing things like you are showing in the example
later in your email (actually much faster than any pure-Ruby logic for
arity resolution). In the case where there was only one arity it
would behave more or less like it does currently. The main change
would be on any same-named method we would need to invalidate. [Note:
This is just one way this could be done and callsite invalidation
would be about the same as what it is now since it would invalidate
based on name. We could do it name+arity. We could do it both ways
even (perhaps name+arity for first case and only name for second).
With all this said, it seems like a good idea to me, but OTOH no
feature is without its caveats. I am more worried about Ruby
programming style than performance and though it seems to pass a smell
test for me...I don't think I am in the 'yeah let's do it camp' yet.
I am probably in the 'someone should play with this' camp.
ing with no special language support:Seems like you can get pretty far though with just a little meta-programm=module Arity
=A0def overload(base)
=A0 =A0define_method(base) do |*args|
=A0 =A0 =A0argc =3D args.size
=A0 =A0 =A0method_name =3D "#{base}_#{argc}"
=A0 =A0 =A0if respond_to?(method_name)
=A0 =A0 =A0 =A0send(method_name, *args)
=A0 =A0 =A0else
=A0 =A0 =A0 =A0raise ArgumentError, "wrong number of arguments (no method= for #{argc} arguments)"
=A0 =A0 =A0end
=A0 =A0end
=A0end
end
class A
=A0extend Arity
=A0overload :foo
=A0def foo_0
=A0 =A0puts "foo with no arguments"
=A0end
=A0def foo_1(arg1)
=A0 =A0puts "foo with 1 argument: #{arg1.inspect}"
=A0end
end
A.new.foo =A0 =A0 =A0 =A0 =A0 # dispatches to A#foo_0
A.new.foo(1) =A0 =A0 =A0 =A0# dispatches to A#foo_1
A.new.foo(1,2) =A0 =A0 =A0# ArgumentError
Gary Wright
--=20
blog: http://blog.enebo.com=A0 =A0 =A0=A0 twitter: tom_enebo
mail: (e-mail address removed)
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.