[ANN] [RCR] Cut-based AOP

T

Trans

|Thanks. I do feel pretty strongly about my first point (classes are
|instantiable) and I think it really comes down to that on the Module
side
|versus cuts being part of the class inheritance heirarchy on the
other. And
|the nature of cut inheritance does separate it from the class
heirarchy.

On the other hand cuts are in essence classes --transparent
*subclasses* to be exact. While you do not instantiate them directly,
they get instantiated as part of the class they cut.

I think the real incongruency comes more from the fact that Class
itself is a subclass of Module. It works okay, but conceptualy it is
odd. And on occasion you have undef a method in Class that's been
defined in Module. I think Matz even metions something liek this in his
recent presentation. It think a better solution would come from having
a "ClassKernel" module which is included in Module and Class, so they
can stand on their own.

Finally, I think cuts are simliar to singleton_classes in that
instantiating them is restricted.

o = Object.new
=> #<Object:0xb7aa96a0>
irb(main):002:0> eigenclass = class << o; self ; end
=> #<Class:#<Object:0xb7aa96a0>>
irb(main):003:0> k = eigenclass.new
TypeError: can't create instance of virtual class
from (irb):3:in `new'
from (irb):3

But I don't think there's any techincal reason they could not be. It's
purposefully disallowed, I guess for conceptual reasons:

VALUE
rb_class_new(super)
VALUE super;
{
Check_Type(super, T_CLASS);
if (super == rb_cClass) {
rb_raise(rb_eTypeError, "can't make subclass of Class");
}
if (FL_TEST(super, FL_SINGLETON)) {
rb_raise(rb_eTypeError, "can't make subclass of virtual class");
}
return rb_class_boot(super);
}

Hey, this still says "virtual class"; _why doesn't his say eigenclass!?
;)

T.
 
I

itsme213

Trans said:
This is to "officially" announce an RCR that I posted to RCR archive
two days ago. I realize the RCR itself is a bit dense and techincial,
so (with thanks to ES) I thought it might be a good idea to provide a
little summary and some examples of what it's all about and why it's a
such a good approach to AOP for Ruby.

You can read the RCR #321 <a
href="http://www.rcrchive.net/rcr/show/321">here</a>.

+1.

I have a few questions I'll need to frame properly, but wanted to say:
Nice work + nice description!
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [ANN] [RCR] Cut-based AOP"

|This is to "officially" announce an RCR that I posted to RCR archive
|two days ago. I realize the RCR itself is a bit dense and techincial,
|so (with thanks to ES) I thought it might be a good idea to provide a
|little summary and some examples of what it's all about and why it's a
|such a good approach to AOP for Ruby.

I understand the basic idea. How about introducing a new method
e.g. "preclude" that works to intercept the methods in the target
class/module, instead of cut. It would be a counterpart of "include"
for mix-in.

matz.
 
S

Sean O'Halpin

How about introducing a new method
e.g. "preclude" that works to intercept the methods in the target
class/module, instead of cut. It would be a counterpart of "include"
for mix-in.

I like the idea but may I point out that "preclude" has a meaning very
close to "exclude". How about "intercept"?

Regards,

Sean
 
A

Alexandru Popescu

Hi!

I would like to comment on this proposal. I can agree right from the beginning that the points here
will be presented from a not-so-rubiesc perspective.

the proposal looks like an method-interception framework, rather than a full blown aop solution.

The proposal is mixin together theoretical aspects of aop with Ruby specific implementation
problems. While this cannot be considered a real problem, what I have noticed is that one of the
main concepts of the AOP pointcuts are completely ignored.

The main idea behind AOP is to be able to define crosscutting concerns. This looks pieces of
functionality that can be used disregarding the OO nature of the project.

While at the first glance the method interception mechanism is one of most important aspects of AOP,
there are a few distinction that must be considered: call vs execution, before, around, after pieces
of advice.

While, maybe leaving alone all these aspects, may be a Ruby implementation constraint, they are
valid AOP principles that will miss from the implementation.

cheers,

/alex
--
w( the_mindstorm )p.

#: Trans changed the world a bit at a time by saying on 10/19/2005 1:56 AM :#
This is to "officially" announce an RCR that I posted to RCR archive
two days ago. I realize the RCR itself is a bit dense and techincial,
so (with thanks to ES) I thought it might be a good idea to provide a
little summary and some examples of what it's all about and why it's a
such a good approach to AOP for Ruby.

You can read the RCR #321 <a
href="http://www.rcrchive.net/rcr/show/321">here</a>. To touch on it's
history: The RCR was developed by Peter Vanbroekhoven and myself over
the course of the last two years[1]. In that time we covered a lot of
territory with regards to AOP, and the RCR itself has undergone a great
deal of scrunity, revision and refinement.

To summaraize the RCR's senitment: The transparent subclass, witch we
have dubbed the Cut, is the best basis for adding AOP to Ruby because
it is fully harmonious with OOP. This is unlike other solutions which
are add-on abstractions tossed on top of the underlying OOP framework.
With cuts one has a building block to construct all sorts of AOP
systems, from simple method hooks to full blown context-oriented
programs. Put simply, the cut is a foundation for AOP, just as the
class is a foundation for OOP.

To demonstrate what you can do with cuts, I present a few simple
examples. I'll start with a very basci one: how to take a prexiting
class and wrap a user interface around it. Nothing fancy. I'll just use
a very small class and the console.

class Race

attr_accessor :distance, :speed, :track

def initialize( distance, speed )
@distance = distance
@speed = speed
@track = 0
end

def reset
@track = 0
end

def run
while track < distance do
self.track += 1;
sleep( 1.0/speed )
end
track
end

end

Simple enough. We can run a race:

Race.new( 10, 2 ).run

Though it goes about it's racey busniess just fine, we have no
indication of any progress of the race. But that's okay actually; it
keeps the Race class clean and focused on its core functionality.
Instead we can use a cut to watch the race.

cut Race::ConsoleViewer < Race
def track=(x)
r = super(x)
print "\e[0E"
print "+" * r
$stdout.flush
r
end
end

Race.new( 10, 2 ).run

This outputs an exra '+' at a time, finishing with 10:

++++++++++

So we see the progress of the race "live" without having to change the
Race class itself in any way. And we can just as easily throw any other
type of interface (gtk, qt, fox, wx, html, and so) around the Race
class in the same manner.

Now lets try a slightly more advance example; one made by Peter quite
some time ago, which demostrates the basis of how cuts could be used
for creating logging aspects. Lets say we have an ftp server class:

class FTPServer

def login(username, passwd)
# code for logging in, return ID for the connection
return connID
end

def logout(connID)
# code for logging out
end

def upload(connID, filename, data)
# code for writing a file
end

def download(connID, finename)
# code for reading a file, returns the data read
end

end

We can create an aspect for it:

module FTPLogging

def login(username, *args)
connID = super
log.print("#{connID}: #{username} logging in on #{Time.new}\n")
connID
end

def logout(connID)
result = super # In case logout returns some result
log.print("#{connID}: logging out on #{Time.new}\n")
result
end

def upload(connID, filename, *args)
result = super # In case logout returns some result
log.print("#{connID}: uploading #{filename} on #{Time.new}\n")
result
end

def download(connID, filename)
data = super
log.print("#{connID}: downloading #{filename} on #{Time.new}\n")
data
end

end

if logging_enabled
cut FTPLoggingCut < FTPServer
include FTPLogging
end
end

Notice the use of a separate module to house the aspect. That way it is
reusable. In this case the aspect's design was made to match the
duck-type of the target class, FTPServer, so we don't need to redirect
any advice in the cut. Though if we wanted to use the aspect on a class
not having the same interface we could easily redirect the advice on a
case by case basis. But even better, using an annotations system we
could create a routine to cut any class so annotated.

Finally, here's a example of how one might use cuts for dynamic
context-oriented programming.

class Account
attr_reader :id, :current
def initialize( id, current )
@id
@current = current
end
def debit( amount )
@current -= amount
end
def credit( amount )
@current -= amount
end
end

module Activiation
def active? ; @active ; end
def activate ; @active = true ; end
def deactivate ; @active = false ; end
end

cut AccountLogging < Account
extend Activation
def debit( amount )
r = super
if AccountLogging.active?
log "Debited account #{id} #{amount} with result #{r}"
end
r
end
end

cut AccountDatabase < Account
extend Activation
def debit( amount )
super
if AccountDatabase.active?
DB.transaction {
record_transaction( -amount )
record_total
}
end
end
def credit( amount )
super
if AccountDatabase.active?
DB.transaction {
record_transaction( amount )
record_total
}
end
end
def record_transaction( amount )
type = amount > 0 ? 'credit' : 'debit'
DB.exec "INSERT INTO transactions (account,#{type}) VALUES
(#{id},#{amount.abs});"
end
def record_total
DB.exec "UPDATE accounts SET total=#{current} WHERE id=#{id};"
end
end

Notice how we can activate and deactivate the aspects on the fly with
the activation module. If we wished we could go even further and create
a completely general purpose (and relatively efficient) context
switching mechinisms.

Oh, one more quick example taken from the RCR itself for those
wondering where the pointcut is, and how one might cross-cut a whole
slew of classes:

ObjectSpace.each_object(Class) { |c|
if c.instance_methods(false).include?:)to_s)
Cut.new(c) do
def :to_s
super.upcase + "!"
end
end
end
end
"a lot of shouting for joy".to_s #=> "A LOT OF SHOUTING FOR JOY!"

Okay, I think that should give a pretty good taste of what "AOP can do
for you" and how Cuts provide a solid, yet easy to use, foundation for
employing AOP on a wide scale. To understand more about why Cuts are
right for the task, covering all the criteria of AOP including
*introduction* and *inspection*, please give the RCR a read.

We hope you find our proposal rewarding and will show your supprt on
RCRchive.

Thanks,
T.


[1] I want to also thank Jamis Buck and everyone else who has spent
time exploring AOP for Ruby with us. Thank You!
 
N

nobuyoshi nakada

Hi,

At Thu, 20 Oct 2005 18:10:55 +0900,
Sean O'Halpin wrote in [ruby-talk:161614]:
I like the idea but may I point out that "preclude" has a meaning very
close to "exclude". How about "intercept"?

The method lookup order feels "post"clude rather than
"pre"clude. ;)
 
T

tad.bochan

Hi ... need help ...

Just had Ruby 1.8.3 installed on our HP-UX box, and it seems to be
really misbehaving... I'm trying to promote Ruby here but this is
giving it bad press.

For example, the following code

#!/usr/local/bin/ruby
p ARGV
ARGV.each do |fname |
puts "File: #{fname}"
loop do
break
end
end

gives .....
xdump param
["param"]
File: param
/home/fcux_dev/tadb/bin/xdump:6: [BUG] Bus Error
ruby 1.8.3 (2005-09-21) [hppa2.0w-hpux11.11]
Abort(coredump)And in fact, this error ([BUG] Bus Error - what is it ?) seems to pop up
at the slightest provocation, although some relatively complex
ruby code seems to run ok.
I didn't do the installation myself, but I suspect that the HP-UX
bundled C compiler was used to do the installation.
Could that be the problem ?





This message and any attachments (the "message") is
intended solely for the addressees and is confidential.
If you receive this message in error, please delete it and
immediately notify the sender. Any use not in accord with
its purpose, any dissemination or disclosure, either whole
or partial, is prohibited except formal approval. The internet
can not guarantee the integrity of this message.
BNP PARIBAS (and its subsidiaries) shall (will) not
therefore be liable for the message if modified.

---------------------------------------------

Ce message et toutes les pieces jointes (ci-apres le
"message") sont etablis a l'intention exclusive de ses
destinataires et sont confidentiels. Si vous recevez ce
message par erreur, merci de le detruire et d'en avertir
immediatement l'expediteur. Toute utilisation de ce
message non conforme a sa destination, toute diffusion
ou toute publication, totale ou partielle, est interdite, sauf
autorisation expresse. L'internet ne permettant pas
d'assurer l'integrite de ce message, BNP PARIBAS (et ses
filiales) decline(nt) toute responsabilite au titre de ce
message, dans l'hypothese ou il aurait ete modifie.
 
P

Peter Vanbroekhoven

Hi,

In message "Re: [ANN] [RCR] Cut-based AOP"

|This is to "officially" announce an RCR that I posted to RCR archive
|two days ago. I realize the RCR itself is a bit dense and techincial,
|so (with thanks to ES) I thought it might be a good idea to provide a
|little summary and some examples of what it's all about and why it's a
|such a good approach to AOP for Ruby.

I understand the basic idea. How about introducing a new method
e.g. "preclude" that works to intercept the methods in the target
class/module, instead of cut. It would be a counterpart of "include"
for mix-in.

Hi Matz,

This is indeed an option we have considered, and not completely dismissed
either. Trans just asked me yesterday whether I could add this on top of
cuts. I think part of the reason that we came up with cuts was because it
is more like subclassing. One argument that I remember is that a class
creates a wrapper around its superclass, and can actually adapt to its
superclass. However, a mix-in cannot adapt to the class it is included in,
because it can be included in many classes and it can't cater to all their
needs. Likewise a superclass cannot adapt to its subclasses. Because the
idea of a wrapper adapting itself to the class it wraps is appealing, but
can only be done if it can wrap only a single class. Hence the idea of a
cut, and not just module 'preclusion'. I don't know what your thoughts are
on this.

Does this mean you like the general idea, of just slipping a module or
class into the class hierarchy and put the wrapper methods there? This
could possibly be used with the :before and :after syntax you've proposed,
with a little extension that allows naming the layer it should go to:

class Foo
def foo
p :foo
end
end

class Bar < Foo
def foo:wrap:Layer
p [:foot, :before]
super
p [:foot, :after]
end
end

All these methods could end up in an (autovivified?) 'precluded' module,
overwrite only methods in that module, and this module can be retrieved
for more fun.

This is just an idea that was floating around in my mind. The syntax (in
case you don't like it) is not the point though, the idea is.

Peter
 
C

Christophe Grandsire

Selon Alexandru Popescu said:
While, maybe leaving alone all these aspects, may be a Ruby implementat= ion
constraint, they are
valid AOP principles that will miss from the implementation.

From the rest of the discussion here about this RCR, I have understood (a=
nd
Trans or others can confirm it I think) that cuts are supposed to be a *b=
asis*,
on which fully-fledged AOP can be built, in a way that fits with Ruby, si=
nce the
base itself fits with Ruby. It's a bottom-up approach, instead of the top=
-down
approach that for instance AspectJ took, and which makes it look very ali=
en to
the rest of Java (in my opinion). I personally believe it's the best appr=
oach,
which is why I voted for this RCR: first built the tools you need, then u=
se
those tools to create a framework. This is in my opinion the only way to =
get
something eventually stable and useful, without looking too much like an =
add-on
but really like part of the language.

In other words, the RCR isn't here to propose full AOP in one go. It is t=
here to
provide what the authors think (and so far I agree) is the only construct
missing to built fully-fledged AOP, in a way that doesn't break with the =
rest
of Ruby, and is easy enough to implement. I guess (but never having used =
it I
might be wrong) that full AOP could be built then as a standard library, =
built
on cuts and ObjectSpace, and/or Ruby's already existing reflection capaci=
ties.

I am always in favour op bottom-up approaches. They may sometimes seem sl=
ower,
but on the long term they result in better code, especially when each too=
l and
addition is built as independently as possible. In a top-down approach, p=
eople
seem often far too tempted to look at their project as a single whole, an=
d thus
to build it in such a way, resulting in code which after some time gets
unmanageable.

I am really in favour of cuts (or maybe some other way to implement the s=
ame
concept, using modules like matz suggested), because they provide a stron=
g,
stable foundation, on which not only AOP can be built, but who knows what=
more?
Cuts extend the notion of modularity in a way different from simple modul=
es, and
this could very well lead to plenty of other things besides AOP which is =
the
main issue they were built for. In other words, don't get too blinded by =
the
issue of fully-fledged AOP when you review this RCR. See it as foundation=
for
it, and maybe quite a few other things.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.
 
E

Eric Mahurin

--- Yukihiro Matsumoto said:
Hi,
=20
In message "Re: [ANN] [RCR] Cut-based AOP"
on Wed, 19 Oct 2005 08:56:59 +0900, "Trans"
=20
|This is to "officially" announce an RCR that I posted to RCR
archive
|two days ago. I realize the RCR itself is a bit dense and
techincial,
|so (with thanks to ES) I thought it might be a good idea to
provide a
|little summary and some examples of what it's all about and
why it's a
|such a good approach to AOP for Ruby.
=20
I understand the basic idea. How about introducing a new
method
e.g. "preclude" that works to intercept the methods in the
target
class/module, instead of cut. It would be a counterpart of
"include"
for mix-in.
=20
matz.

+1, if it is what I think you mean. Is this what you mean?

class C
def foo
"bar"
end
end

c =3D C.new
c.foo # =3D> "bar"

module Braces
def foo
"{"+super+"}"
end
end

class C
preclude Braces
end

c.foo # =3D> "{bar}"

module Brackets
def foo
"["+super+"]"
end
end

class C
preclude Brackets
end

c.foo # =3D> "[{bar}]"

module Braces
remove_method :foo
end

c.foo # =3D> "[bar]"

I really like this. I don't see anything you couldn't do with
this that you can with the cut-based-AOP. And it seems so much
simpler.




=09
=09
__________________________________=20
Yahoo! Mail - PC Magazine Editors' Choice 2005=20
http://mail.yahoo.com
 
P

Pit Capitain

Eric said:
module Braces
remove_method :foo
end

c.foo # => "[bar]"

I really like this. I don't see anything you couldn't do with
this that you can with the cut-based-AOP. And it seems so much
simpler.

I like it too, but instead of having to remove methods from modules, it
would be better if we could "exclude" modules from the inheritance
chain. Will this be possible in Ruby 2?

Another question: how would I "preclude" a module to an instance?

Module: include <-> preclude
Instance: extend <-> ?? (pretend :)

Regards,
Pit
 
D

Daniel Schierbeck

+1

I only have one concern: I think the syntax is kinda weird. It resembles
the class definition syntax, but I can't see why it should. When you
write "class A < B" you're saying "class A inherits from class B" or
"class A is affected by class B". If we apply the same to "cut A < B",
it would be "cut A is affected by class B", which isn't the case. Why
not use "cut A > B", "cut A affects class C". The singleton syntax could
be like this "cut >> obj".


Just my .16 Yen
Daniel
 
E

Eric Mahurin

--- Pit Capitain said:
Eric said:
module Braces
remove_method :foo
end
=20
c.foo # =3D> "[bar]"
=20
I really like this. I don't see anything you couldn't do with
this that you can with the cut-based-AOP. And it seems so much
simpler.
=20
I like it too, but instead of having to remove methods from
modules, it=20
would be better if we could "exclude" modules from the
inheritance=20
chain. Will this be possible in Ruby 2?

Yep, that might be useful too. So you'd do this instead:

class C
exclude Braces
end

Another end case you have to think about is if a class
precludes the same module twice. Does it wrap the method
twice? And if so, does "excluding" it remove both wraps.
Another question: how would I "preclude" a module to an
instance?
=20
Module: include <-> preclude
Instance: extend <-> ?? (pretend :)
=20
Regards,
Pit

Yes, I was just thinking about that too. "pretend" was the
first that came to my mind too :) But, you could also do it
manually:

class <<obj;preclude XXX;end


Another possiblity for a name instead of "preclude" would be
"wrap":

class C
wrap Brackets
wrap Braces
end

c.foo # =3D> "{[foo]}"

class C
unwrap Brackets
end

c.foo # =3D> "{foo}"




=09
=09
__________________________________=20
Yahoo! Mail - PC Magazine Editors' Choice 2005=20
http://mail.yahoo.com
 
A

Alexandru Popescu

#: Christophe Grandsire changed the world a bit at a time by saying on 10/20/2005 2:20 PM :#
Trans or others can confirm it I think) that cuts are supposed to be a *basis*,
on which fully-fledged AOP can be built, in a way that fits with Ruby, since the
base itself fits with Ruby. It's a bottom-up approach, instead of the top-down
approach that for instance AspectJ took, and which makes it look very alien to
the rest of Java (in my opinion). I personally believe it's the best approach,
which is why I voted for this RCR: first built the tools you need, then use
those tools to create a framework. This is in my opinion the only way to get
something eventually stable and useful, without looking too much like an add-on
but really like part of the language.

In other words, the RCR isn't here to propose full AOP in one go. It is there to
provide what the authors think (and so far I agree) is the only construct
missing to built fully-fledged AOP, in a way that doesn't break with the rest
of Ruby, and is easy enough to implement. I guess (but never having used it I
might be wrong) that full AOP could be built then as a standard library, built
on cuts and ObjectSpace, and/or Ruby's already existing reflection capacities.

I am always in favour op bottom-up approaches. They may sometimes seem slower,
but on the long term they result in better code, especially when each tool and
addition is built as independently as possible. In a top-down approach, people
seem often far too tempted to look at their project as a single whole, and thus
to build it in such a way, resulting in code which after some time gets
unmanageable.

I am really in favour of cuts (or maybe some other way to implement the same
concept, using modules like matz suggested), because they provide a strong,
stable foundation, on which not only AOP can be built, but who knows what more?
Cuts extend the notion of modularity in a way different from simple modules, and
this could very well lead to plenty of other things besides AOP which is the
main issue they were built for. In other words, don't get too blinded by the
issue of fully-fledged AOP when you review this RCR. See it as foundation for
it, and maybe quite a few other things.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

I would probably agree with you with some small exceptions:

1/ AspectJ was alien to java because it was meant to provide a full AOP implementation. Meanwhile,
considering AJ alien is like saying cut-s are alien to ruby, just because they are trying to
introduce a new idea.

2/ in a bottom-up approach as you are considering the cut-s approach, you can miss some of the top
views. And this will result in the impossibility to have this top scenarios implemented or working.

3/ if you consider cut-s just an implementation aspect of AOP support in Ruby, than I will agree
that it looks quite appealing. But I have read a full set of examples which are based directly on
them. I wasn't able to see pointcut definitions, and without them - as I already pointed - there is
no aop.

I am not trying to argue on the main idea or on the effort this RCR took. It is indeed a fantastic
effort and I appreciate it. I just feel that some aspects should be considered right from the
beginning instead of just ignoring them. We have the advantage that other solutions are pretty
advanced at this moment and learning from their past is a good thing to do.

respectfully,

/alex
 
T

Trans

Hi Matz,

Yukihiro said:
I understand the basic idea. How about introducing a new method
e.g. "preclude" that works to intercept the methods in the target
class/module, instead of cut. It would be a counterpart of "include"
for mix-in.

Yes, this is in the RCR:

Additionally, Cuts exist in proxy form to allow modules to be
"premixed". This is analogous to proxy classes which allow modules to
mixin to the class hierarchy. So too does a proxy-cut include a module,
albeit preclusive rather the inclusive in its effect. We offer the
module command #preclude to serve as designator of this purpose.

module A
def m ; "<#{super}>" ; end
end
Class T
preclude A
def m ; "okay" ; end
end
T.new.m #=> "<okay>"


I am amazed how quickly you've latched onto the most probable usage. I
have known for sometime that "preclude" would be the most utilized part
of this. But I have avoided stressing it becuase it is important that
it too be supported by good foundation, which is the Cut. Just as there
is a *proxy-class* to *mixin* modules, there'd be a *proxy-cut* to
*premix* them. Although precluding modules will certainly be utilized
most, I do not see any benefit in hiding the underlying class which
facilitates them from the programmer.

OTOH, perhaps you have a different idea for the implementation of
precluded modules; one that avoids any sort of cut/proxy-cut class
altogether. If so, I must tell you, I am cautious of such an approach
because it implies "adding-on" rather than "integrating". IMHO,
integrating this "atomic-aspect" formally into the OO class heirarchy
would be of greater benefit to Ruby, and potentially influential on OOP
in general. From a comparitive perspective, it is the difference
between Ruby simply having an extra feature and Ruby having a new and
original object-oriented feature.

T.
 
E

Eric Mahurin

--- Trans said:
Hi Matz,
=20
Yukihiro Matsumoto wrote:
=20
=20
Yes, this is in the RCR:
=20
Additionally, Cuts exist in proxy form to allow modules to be
"premixed". This is analogous to proxy classes which allow
modules to
mixin to the class hierarchy. So too does a proxy-cut include
a module,
albeit preclusive rather the inclusive in its effect. We
offer the
module command #preclude to serve as designator of this
purpose.
=20
module A
def m ; "<#{super}>" ; end
end
Class T
preclude A
def m ; "okay" ; end
end
T.new.m #=3D> "<okay>"

Trans/Peter,

What does a "cut" do that "preclude" doesn't? It seems like
you still can manage the AOP methods through modules instead of
cuts. And you can stack these. Can you give a scenario where
"preclude" doesn't "cut" it :)

I still think something like "wrap" would be a better word.=20
"preclude" may describe the inheritance hierarchy kind of, but
not the functionality from a user's perspective.



=09
__________________________________=20
Yahoo! Music Unlimited=20
Access over 1 million songs. Try it free.
http://music.yahoo.com/unlimited/
 
T

Trans

Hi--

Alexandru said:
Hi!

I would like to comment on this proposal. I can agree right from the beginning
that the points here will be presented from a not-so-rubiesc perspective.
the proposal looks like an method-interception framework, rather than a
full blown aop solution.

Yes, in a way you are correct. Ruby provides enough reflective
functionality that it is not neccessary. In other words there is no
need for what you call "full-blown" aop b/c the system already supports
all that is neccessary to achieve full blown aop. This is not to say
there are no areas in which it can be improved, indeed there are. Cuts
is one of those. Peter and I already have developed much of the rest
too: ways to strengthen the hooks and callbacks as well as better EAOP
(event-based AOP) than provided by set_trace_func. But these are for
another day, and more importantly, they do not cover the the majority
of AOP usecase, which Cuts squarely target.
The proposal is mixin together theoretical aspects of aop with Ruby specific
implementation problems.

I would disagree completely. The proposal narrows down the core of AOP
(namely the 2nd form of AOP implemention) to a formal OOP construct.
The Cut can be implemented in any OOP system, from Simula 67 to
Smalltalk. In fact this has been all along and still is Very Important
to me. I did not want a construct suitable only to Ruby, but something
generally applicable.
While this cannot be considered a real problem, what I have noticed is that one of > the main concepts of the AOP pointcuts are completely ignored.

Pointcuts are mentioned, and why there is no need to have a special
"pointcut thing". Pointcut is a concept of selecting joinpoints
--another abstract term, meaning the place in code to intercept. Well,
we have exactly that. You can specify on small scale of one class and
it's methods, or large scale using ObjectSpace. It is not neccessary to
make a pointcut thing when we already have those. But if you want you
could write your own extermely easily, probably in one line of code.
The main idea behind AOP is to be able to define crosscutting concerns. This looks > pieces of functionality that can be used disregarding the OO nature of the > project.

Sorry, I do not full understanding. We do address crosscutting, and OO
nature.
While at the first glance the method interception mechanism is one of most
important aspects of AOP, there are a few distinction that must be considered:
call vs execution, before, around, after pieces of advice.

before and after advice are subset of around advice. We decided it was
just easer to have the one than worry about three since before and
after are merely sugar of around. You are right about call vs.
execution though. In this case it a matter of the 80/20 rule. We make
80% of the need easy (though it's probably more like 99/1 in this
case). If you _must_ have call interception then there are more advance
techinuques to use, such as set_trace_func. We've also discussed
method_dispatching hook. But understand these have much greater impact
on performance than method interception. This is important reason call
interception is not specifically part of this RCR. (But who knows?
Maybe someone will come up with an easy idea for this too).
While, maybe leaving alone all these aspects, may be a Ruby implementation
constraint, they are valid AOP principles that will miss from the implementation.

There are some. Because Ruby is not 100% OOP, though it is very close,
you can not cut conditionals for example. You've pointed out call
interception already and there are other marginal areas. Ruby itself
has some limitations that effect this. Combined with Ruby's ability to
reflect on itself, Cut-based AOP covers the vast majoirty of AOP needs.
And as Ruby improves so does the reach of cuts.

T.
 
T

Trans

Daniel said:
+1

I only have one concern: I think the syntax is kinda weird. It resembles
the class definition syntax, but I can't see why it should. When you
write "class A < B" you're saying "class A inherits from class B" or
"class A is affected by class B". If we apply the same to "cut A < B",
it would be "cut A is affected by class B", which isn't the case. Why
not use "cut A > B", "cut A affects class C". The singleton syntax could
be like this "cut >> obj".

Your .16 Yen is appreciated :) In fact we have discussed similar
notation:

class A > Ac
# advice
end

We decided against, mainly because it looks too much like normal
subclassing. though it is certaintly a possibility.

How I say 'cut Ac < A' is "cut Ac cuts A.", though I normally drop the
first 'cut', "Ac cuts A".

T.
 
T

Trans

Eric said:
Another end case you have to think about is if a class
precludes the same module twice. Does it wrap the method
twice? And if so, does "excluding" it remove both wraps.

No. The idea is that it would use a proxy-cut, just as a module uses a
proxy-class. So like modules that are included, Once included they are
not included again. A limitation? Yes. But one we've come acustom to in
the way Ruby's inhertiance works.

Exluding aspect modules is potentially expensive operation, espeacilly
if you include and exclude a lot. But it could be interesting. I htink
it essentially amounts to selector namespaces.

T.
 
S

stevetuckner

--------------030105090308060702000305
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Eric Mahurin wrote:




No. The idea is that it would use a proxy-cut, just as a module uses a
proxy-class. So like modules that are included, Once included they are
not included again. A limitation? Yes. But one we've come acustom to in
the way Ruby's inhertiance works.

Exluding aspect modules is potentially expensive operation, espeacilly
if you include and exclude a lot. But it could be interesting. I htink
it essentially amounts to selector namespaces.
Please expand on that last sentence please. Could this cut feature be
used to implement selector namespaces?

Steve Tuckner


--------------030105090308060702000305--
 

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

Similar Threads

easy AOP right now using evil.rb 2
RCR 13 0
RCR for Range.rand 0
AOP bigger picture 3
The likes of AOP (1 of 2) 1
ideas for an RCR: variable locality 16
aop in ruby 2
No Thing Here vs Uninitialized and RCR 303 21

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top