T
Trans
Eric said: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
Given the implementation of proxy-cuts, it is basically the exact same
difference between class and module. If not familar with how a module
is inclued into the class hierarchy via a proxy-class, have a look in
Pickaxe. It explains it well. Also cuts aren't instatiable on their own
so they are even more like modules in that one respect. So the answer
is "very little".
There is one difference though that can in certain circumstance be
problematic if only a module solution were available: the Dynamic
Module Inclusion Problem. You can see this problem with normal modules.
module X
def x; 1; end
end
class C
include X
end
c = C.new
p c.x #=> 1
module Z
def z; "z"; end
end
module X ; include Z ; end
p c.z #=> NoMethodError
We've include X into class C, then instatiated an instance of it. If
later we include another module Z into module X, it will not show up in
C. If we had included Z directly into class C instead we would not have
this problem. In the same manner this would effect precluded modules,
and while not an utter show stopper, it is more likely to occur for
cuts b/c of the nature of AOP, esspecially if were talking about making
them even more dynamic, including and extracting them on the fly.
Note, the Dynamic Module Problem is an ackowledged issue with Ruby and
has nothing to do with cuts themselves. From what I understand, it is
not a simple problem to solve and would take a great deal of effort and
a good bit of alteration to Ruby --if it is even efficenty possible.
Other then that I'm not sure if there is anything *undoable*. You can
program Ruby without every subclassing too; modules do everyhting you
need. But even so underthehood the subclass is still there in proxy
form. So I'm not sure if there is really anything to gain from not
providing the Cut to the end user given that it's already underneath
anway.
And actually it is nicer to use when your just need is to cut a
specific class:
class C
def x ; '1' ; end
end
cut A < C
def s ; '{' + super + '}' ; end
end
vs.
class C
def x ; '1' ; end
end
module A
def s ; '{' + super + '}' ; end
end
class C
preclude A
end
There is no need to reopeon the class.
Ah, there is one more thing. Using Cuts could allow for cutting cuts, a
way to insert advice prior to other prexisting advice.
class C
def x ; '1' ; end
end
cut A < C
def s ; '{' + super + '}' ; end
end
C.new.x #=> {1}
cut B < A
def s ; '[' + super + ']' ; end
end
C.new.x #=> {[1]}
Notice cuts stack inversely when cutting each other. We never decided
if this would be allowed or not, but it is a possibility. It would not
be as tidy if only modules were availble, moreovor it would definitely
come-up against the Dynamic Module Inclusion Problem.
I still think something like "wrap" would be a better word.
"preclude" may describe the inheritance hierarchy kind of, but
not the functionality from a user's perspective.
I didn't like #preclude at first, but nothing ever felt as right
considering its parallel to #include. There is #prepend, but I'm sure
that will be matched against #append_features which #include uses. But
if you think about it preclude means essentially "forgone conclusion".
That's pretty close.
T.