[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: before, after and around Ruby 1.9

Yukihiro Matsumoto

9/6/2007 1:47:00 AM

Hi,

In message "Re: before, after and around Ruby 1.9"
on Thu, 6 Sep 2007 10:32:03 +0900, Joel VanderWerf <vjoel@path.berkeley.edu> writes:

|What if you want to reopen _without_ the "around" semantics?

I thought we need to remove the previous one first.

|Could we have these two variations:
|
|class Foo < Foo # <-- This is a type error in 1.8
| def foo; super; end # AROUND
|end
|
|class Foo
| def foo; super; end # REDEFINE
|end
|
|At least that is a conservative extension.

Or maybe providing two supers, one for the current behavior, the other
for the new. I don't whatever name is suitable for new super yet,
however.

matz.

2 Answers

Rick DeNatale

9/6/2007 2:57:00 AM

0

On 9/5/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

> |Could we have these two variations:
> |
> |class Foo < Foo # <-- This is a type error in 1.8
> | def foo; super; end # AROUND
> |end
> |
> |class Foo
> | def foo; super; end # REDEFINE
> |end
> |
> |At least that is a conservative extension.
>
> Or maybe providing two supers, one for the current behavior, the other
> for the new. I don't whatever name is suitable for new super yet,
> however

Hi Matz,

super for this new usage just doesn't feel right to me.

Isn't this really looking for syntactic sugar for something like:

class Foo #reopen

alias_method :old_foo, :foo

def foo
old_foo #around
end
end

So as to avoid needing to explicitly alias the method and come up with a name?

Perhaps instead of super in this case something in the vein of old,
or previous.

Alternatively what about instead of def

class Foo
around foo
#do something
foo
# do something else
end
end

Which I would see as internally aliasing the existing foo, and
resolving reference to fo in the new methods body to the alias.

Or instead of around, how about wrap, with a corresponding unwrap to
back out the wrapper method?


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Brian Mitchell

9/6/2007 4:15:00 AM

0

On 9/5/07, Rick DeNatale <rick.denatale@gmail.com> wrote:
> On 9/5/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
>
> > |Could we have these two variations:
> > |
> > |class Foo < Foo # <-- This is a type error in 1.8
> > | def foo; super; end # AROUND
> > |end
> > |
> > |class Foo
> > | def foo; super; end # REDEFINE
> > |end
> > |
> > |At least that is a conservative extension.
> >
> > Or maybe providing two supers, one for the current behavior, the other
> > for the new. I don't whatever name is suitable for new super yet,
> > however
>
> Hi Matz,
>
> super for this new usage just doesn't feel right to me.
>
> Isn't this really looking for syntactic sugar for something like:
>
> class Foo #reopen
>
> alias_method :old_foo, :foo
>
> def foo
> old_foo #around
> end
> end
>
> So as to avoid needing to explicitly alias the method and come up with a name?
>
> Perhaps instead of super in this case something in the vein of old,
> or previous.
>
> Alternatively what about instead of def
>
> class Foo
> around foo
> #do something
> foo
> # do something else
> end
> end
>
> Which I would see as internally aliasing the existing foo, and
> resolving reference to fo in the new methods body to the alias.
>
> Or instead of around, how about wrap, with a corresponding unwrap to
> back out the wrapper method?
>

Kind of ugly. I'll stick with my def thanks. I did like some of the
early code examples/ideas that Matz has put into past presentations.

The above would also make recursive calls quite hard. The bigger
question comes with the combination of two smaller problems: arguments
and recursion. How do we want to treat stacked methods are these like
methods in their own modules or are we going to keep different calling
semantics?

Consider an initial class with a simple method:

class Example
def fib(n)
if n > 1
fib(n - 2) + fib(n - 1)
else
1
end
end
end

Now we reopen the class and add a new fib:

class Example
def fib(n, prefix = 'Calculating fib of ')
puts prefix + n.to_s
super(n)
end
end

So in this example, calling fib(2) on an instance of Example would
yield a simple:

Calculating fib of 2
Calculating fib of 0
Calculating fib of 1

That works well because we can always call super with correct
arguments BUT the recursion in the first method could possibly cause
problems. The first method only knows about its own argument so it
forces the calculation to default after the first fib call. So fib(2,
'Try ') would give the confusing output of

Try 2
Calculating fib of 0
Calculating fib of 1

Not so great. So how would one reconcile this problem? Would recursive
calls directly call the current method? Would we use something like
Erlang's reloading which differentiates calls that explicitly give a
target (i.e. self in this case) vs ones that make it implicit?

I do think super is an underused feature of Ruby (generally because it
is so easy to alias things in Ruby). I think the idea is wonderful but
there needs to be serious consideration on some of the calling
mechanisms. The above example is contrived. It might be appropriate to
use the same rules as regular non-stacked super methods.

I can't quite tell what feels right in this case but I think being
able to recurse properly should be a top priority.

Brian.