Method wrapping

H

Hal Fulton

I've come late into the thread on this, and I haven't read all
the discussion.

I'll address this to Guy Decoux, as he is one of the top N
most knowledgeable people here, for small values of N.

Guy:

I just have some questions about the way this is going to work
in Rite.

1. Is it possible to add multiple wrappers for a method or
not? Do they "stack"?

2. If they do stack, is it possible to redefine a method as we
are used to doing? Or will that simply add a new wrapper?


Merci,
Hal
 
T

ts

H> 1. Is it possible to add multiple wrappers for a method or
H> not? Do they "stack"?

H> 2. If they do stack, is it possible to redefine a method as we
H> are used to doing? Or will that simply add a new wrapper?

Only matz know the response to these questions.


Guy Decoux
 
H

Hal Fulton

ts said:
H> 1. Is it possible to add multiple wrappers for a method or
H> not? Do they "stack"?

H> 2. If they do stack, is it possible to redefine a method as we
H> are used to doing? Or will that simply add a new wrapper?

Only matz know the response to these questions.

OK, I thought maybe it was defined on the core list (which
I don't read).

Matz??

Hal
 
P

Paul Brannan

1. Is it possible to add multiple wrappers for a method or
not? Do they "stack"?

IIRC (and if my notes are accurate), I think Matz indicated in his talk
that this would be possible. If there is more than one wrap for a given
method, then the wrap methods are "stacked in order of definition,"
though I'm not sure exactly what that means.

Paul
 
Y

Yukihiro Matsumoto

Hi,

In message "Method wrapping"

|I'll address this to Guy Decoux, as he is one of the top N
|most knowledgeable people here, for small values of N.
|
|Guy:
|
|I just have some questions about the way this is going to work
|in Rite.

He might have his own version of Ruby with method combination, it's my
responsibility to define Ruby2 behavior:

|1. Is it possible to add multiple wrappers for a method or
|not? Do they "stack"?

They stack.

|2. If they do stack, is it possible to redefine a method as we
|are used to doing? Or will that simply add a new wrapper?

Re-defining primary method (method without :pre, :post, or :wrap)
replaces old primary methods.

matz.
 
S

Shashank Date

Paul Brannan said:
IIRC (and if my notes are accurate), I think Matz indicated in his talk
that this would be possible.

Judging from that one occasion when I was sitting next to you,
I have started believing that your notes are pretty accurate, Paul. :)
 
H

Hal Fulton

Yukihiro said:
He might have his own version of Ruby with method combination, it's my
responsibility to define Ruby2 behavior:

Of course.

By the way, I didn't intend any insult or impropriety by asking
this of Guy. I know that you are the ultimate authority, but I
thought that this had perhaps been well-discussed among others
without my knowing.

Frankly, Matz, I feel a little guilty every time I ask you a
question; because I know that every minute you spend answering
that type of question is a minute that you are not spending on
more important matters.
|2. If they do stack, is it possible to redefine a method as we
|are used to doing? Or will that simply add a new wrapper?

Re-defining primary method (method without :pre, :post, or :wrap)
replaces old primary methods.

Since I have already opened this issue, I will clarify by asking
two more specific questions:

1. If I want to redefine a "secondary" method (or whatever I should
call it), can I do so? It seems that an attempt to redefine
foo:pre would simply add a new foo:pre.

2. If the primary method is redefined, do the "secondary" methods
get cancelled? Or do they simply remain in place?

As always, thanks for your time, and thanks for Ruby...

Hal
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Method wrapping"

|1. If I want to redefine a "secondary" method (or whatever I should
|call it), can I do so? It seems that an attempt to redefine
|foo:pre would simply add a new foo:pre.

They are auxiliary methods. And "no", you can't "redefine" those
methods. You have to remove them first, using no-yet-designed method
reflection API.

|2. If the primary method is redefined, do the "secondary" methods
|get cancelled? Or do they simply remain in place?

They remain in place. They will be removed altogether when you remove
the method using "remove_method" method.

matz.
 
T

T. Onoma

Since I have already opened this issue, I will clarify by asking
two more specific questions:

1. If I want to redefine a "secondary" method (or whatever I should
call it), can I do so? It seems that an attempt to redefine
foo:pre would simply add a new foo:pre.

I doubt we should be able to redine secondary methods. If you do this they
will have to be indexed in someway, and a means for referencing those indexes
becomes neccessary. Because the indexes have no semantic value, they would
not be generally usable. For example, if I had a class using 3 wraps, and you
created a subclass of it that redinfined wrap #2, if I later "improved" my
class by placing another warp before #2, your subclass would no longer work.
(Similiar to below)
2. If the primary method is redefined, do the "secondary" methods
get cancelled? Or do they simply remain in place?

Using just def to redefine method will neccessarily destroy all wraps
otherwise, you run into this:

class A # An external library class
def riot
print "P"
end
end

class B < A # My subclass
def riot
print "Q"
end
end

If later, the library maintainer decided to add an AOP method:

class A # An external library class
def riot
print "P"
end
def riot:wrap
print "*"
end
end

B class will no longer work as expected.

-t0
 
T

T. Onoma

responsibility to define Ruby2 behavior:
|1. Is it possible to add multiple wrappers for a method or
|not? Do they "stack"?

They stack.

|2. If they do stack, is it possible to redefine a method as we
|are used to doing? Or will that simply add a new wrapper?

Re-defining primary method (method without :pre, :post, or :wrap)
replaces old primary methods.

I would like to point out that their is some inconsistentcy in this behavior,
in that def behaves differently depending on whether it is defined in class
augmentation or a subclass.

class A < X
def riot
super
print "P"
end
end

class A
def riot # this redifines
super
print "R"
end
end

class B < A
def riot
super # this wraps
print "W"
end
end

The def syntax is the same but each has different semantic meaning (effects
code readability/code maintainence).

It is important to understand that Ruby already has a wrapping facility using
subclasses. And singletons act similiarly. So it would be more consistent to
naturally extend that to in-class wraps. We can do this without having to add
special syntax sugar (the colon).

Furthermore, from what I can tell, the current proposal does not address super
wrapping. An issue have delt with in my AOP work.

Please refer to:

http://www.rubygarden.org/ruby?AspectOrientedRuby

for more information on all this.

-t0
 
T

T. Onoma

|2. If the primary method is redefined, do the "secondary" methods
|get cancelled? Or do they simply remain in place?

They remain in place.

I don't think that's a desirable behavior. See previous post.

Also, the hooks (wraps) of a method are generally dependent on how that method
works. If you redefine a method without removing the hooks, your new method
will have to conform to the expectations of those hooks, or things will
break.

-t0
 
G

Gavin Sinclair

I don't think that's a desirable behavior. See previous post.
Also, the hooks (wraps) of a method are generally dependent on how that method
works. If you redefine a method without removing the hooks, your new method
will have to conform to the expectations of those hooks, or things will
break.

If you are redefining your own method in development, you know what
you're doing - you're probably just mucking around - and can sort out
the wrappers yourself.

If you are redefining someone else's method in production, on your own
head be it. You should be keeping to the same interface of the
original, or else other code is likely to break.

Wrappers don't depend on the implementation of a method, as you
assert. They depend on the interface. The wrappers should have no
real side-effect anyway, I suspect, except for logging, asserting, ...

It is certainly a curly area, though.

Gavin
 
T

T. Onoma

If you are redefining your own method in development, you know what
you're doing - you're probably just mucking around - and can sort out
the wrappers yourself.

Since we are discussing the addition of AOP features to the core language, I
don't think factors of what one would do just "mucking around" are good
criteria.
If you are redefining someone else's method in production, on your own
head be it. You should be keeping to the same interface of the
original, or else other code is likely to break.

Exactly, and to do this requires understanding the interface. And more times
than not, if you are REDEFINING a method in this manner, your doing it in
totality. Juggling the hooks from before is not condusive. You'll end up
remove_method'ing them all anyway.
Wrappers don't depend on the implementation of a method, as you
assert. They depend on the interface. The wrappers should have no
real side-effect anyway, I suspect, except for logging, asserting, ...

Of course, I was referreing to the interface of the implementation. Sorry, for
not being more specific.

As for real side effects. What do you mean? That we should only expect them to
be used for certain cases like logging, asserting, ....? AOP has much more
potential than this.
It is certainly a curly area, though.

If you think of wraps as sort-of class defineable singletons, that is to say,
singletons that you define literally in your class definitions. It then makes
a whole lot more sense.

-t0
 
T

Thomas Fini Hansen

Exactly, and to do this requires understanding the interface. And more times
than not, if you are REDEFINING a method in this manner, your doing it in
totality. Juggling the hooks from before is not condusive. You'll end up
remove_method'ing them all anyway.

OK, I'll add my take from the perspective of someone that's not played
with Ruby that long.

My first reaction to all this wrapper talk was 'WTF?', because it
seemed very odd to me. But I think I've gotten the idea now.

As I see it, wrapping is for those 'I want this too' situations, you
don't really want to change the original method, but you need a bit of
extra code. Debugging statements and logging of use springs to
mind. The important part being that the extra code doesn't muck with
the interface.

If you really want to change the how the method works, you do as you
do now, redefining the method itself, possibly renaming the old.

I might be wrong though.
 
T

T. Onoma

Exactly, and to do this requires understanding the interface. And more
times than not, if you are REDEFINING a method in this manner, your doing
it in totality. Juggling the hooks from before is not condusive. You'll end
up remove_method'ing them all anyway.

I forgot to add that if you are not redefining, then your adding an additional
wrap, as you do with subclasses. Access to a particular indexed wrap just
won't be useful except for "mucking around", as Gavin put it. So if there's
some tucked away method for doing it, that's fine. But it shouldn't be a
"common spec" or part of the def syntax in anyway.

-t0
 
T

T. Onoma

OK, I'll add my take from the perspective of someone that's not played
with Ruby that long.

My first reaction to all this wrapper talk was 'WTF?', because it
seemed very odd to me. But I think I've gotten the idea now.

It is rather odd. Aspect Oriented Programming is still rather new and I thnk
has a lot of utepped potential yet.
As I see it, wrapping is for those 'I want this too' situations, you
don't really want to change the original method, but you need a bit of
extra code. Debugging statements and logging of use springs to
mind. The important part being that the extra code doesn't muck with
the interface.

Let me give you an example of what you can do with AOP. I wrote a Ruby script
that took an object and wrapped every method (using an eval hack) so that all
changes to its instance varables were passed over to a whole different script
which displayed all the info in a nice neat way. I got 100% seperation of
concern between my generic object and the inteface code to watch it in
action. And this in not only useful for debugging, and what not. Tie that
info to a GUI toolkit script and you can farily easily create GUI front ends
for your program, without touching the original code --simple automated
interaction between object and user.
If you really want to change the how the method works, you do as you
do now, redefining the method itself, possibly renaming the old.

Doing a wrap is little more than calling another method:

def this
print "A"
end

def that
print "("
this
print ")"
end

I have wrapped this with that. The difference with AOP wrapping is that it
gives you a GENERIC means of accomplishing the same thing. So that all other
methods calling on this do not have to be change to call on that. It isn't a
big deal in a single class b/c I can just change the insides of this, but
cutting across seperate classes, libraries, programs, etc. That isn't doable.
I might be wrong though.

Nope not wrong, there's just even more to it.

-t0
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Method wrapping"

|> They remain in place.
|
|I don't think that's a desirable behavior. See previous post.

Which one? We have too many "previous" posts here.

matz.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Method wrapping"

|I would like to point out that their is some inconsistentcy in this behavior,
|in that def behaves differently depending on whether it is defined in class
|augmentation or a subclass.
|
| class A < X
| def riot
| super
| print "P"
| end
| end
|
| class A
| def riot # this redifines
| super
| print "R"
| end
| end
|
| class B < A
| def riot
| super # this wraps
| print "W"
| end
| end
|
|The def syntax is the same but each has different semantic meaning (effects
|code readability/code maintainence).

I don't get your point. Perhaps your example should be:

class A < X
def riot
print "P"
end
end

class A
def riot # this redifines
print "R"
end
end

class B < A
def riot
super # this wraps
print "W"
end
end

Right?

|It is important to understand that Ruby already has a wrapping facility using
|subclasses. And singletons act similiarly. So it would be more consistent to
|naturally extend that to in-class wraps. We can do this without having to add
|special syntax sugar (the colon).

But how? I don't see concrete syntax you are saying.

matz.
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,813
Members
47,357
Latest member
sitele8746

Latest Threads

Top