On Wed, 19 Oct 2005, Eric Mahurin wrote:

> What's the reason for naming the cut?  In all of the code I've
> seen so far, the actual cut is never used.  So instead of:
>
> cut C < A ... end
>
> why not:
>
> cut < A ... end
>
> or:
>
> cut A ... end
>
> The only thing I can think of off hand is that you might want
> to remove the cut down the road.

Well, naming the cut is interesting if you want to reopen the cut and 
change some methods. And in general for managing the cuts, like removing.

Just like with classes, if you don't want to store the cut or don't want 
to waste a constant on it, use the constructor:

   Cut.new(A) do ... end

> Conceptually, I think it is easier to think of this cut
> operating on the parent class (make it look like you're just
> reopening the class).  You could think of this "cut" as
> something just like "class" except that the superclass is
> treated as the previous definition of "class".  This also would
> extend well to making a cut on the meta class of an object:
>
> cut <<obj ... end

Sure, and this is exactly how you can do it.

>> From the syntax you proposed, it would be something like this I
> believe:
>
> cut A < <<obj ... end

What makes you say so? Given that subclassing is done like "class A < B" 
it does not mean that opening the singleton class of B look like "class A 
< << B". Some here. If you want to give the cut a name, use "cut A < B", 
if you want to cut the metaclass, use "cut << B", and if you want an 
anonymous cut, use "Cut.new(A)".

> I didn't see anything in the proposal about cutting the
> meta-class of an object, but the above seems like what the
> syntax would be.  Naming the cut just seems unnecessarily
> verbose and complicates the concept.

Then it must be missing from the proposal, it was certainly intended to be 
possible. As for the unnecessary complexity, I don't agree. Naming the cut 
allows you to access it again, and change methods ro remove them, etc. It 
gives you a handle on them.

> Here are 2 other ideas that accomplish the majority of what you
> are talking about without being so grandiose:
>
> - have another type of def/#define_method (maybe
> redef/#redefine_method) that allows redefinition of a method
> such that "super" is treated as the previous definition.

In a way this is what Matz wanted to do with "def method:wrap", it's just 
a different syntax. A big problem with this is how to manage these 
redefinitions. How do you propose we redefine or remove a specific 
rededinition if there are many for the same method?

> - have another keyword like "super" that means previous
> definition.

We've been over that in our discussions before. One problem is that that 
keyword can be hidden inside an eval and all, which makes it impossible to 
determine whether the previous definition is actually called. This causes 
a problem with garbage collecting previous method definitions, as it is 
impossible to determine the dead ones automatically in all possible cases.

Also, this does still not allow the redefinitions to be managed in any 
sensible way.

> Right now you can actually manually do something like the
> above:
>
> class C
>  def foo;"foo";end
> end
>
> c = C.new
>
> c.foo # => "foo"
>
> class C
>  foo1 = instance_method(:foo)
>  define_method(:foo) { "{"+foo1.bind(self).call+"}" }
> end
>
> c.foo # => "{foo}"
>
> class C
>  foo1 = instance_method(:foo)
>  define_method(:foo) { "["+foo1.bind(self).call+"]" }
> end
>
> c.foo # => "[{foo}]"
>
> Pretty sweet, huh?  I wasn't sure if foo1 kept the previous
> definition until I tried it, but apparently it does.
> 
> Maybe just an easier way to do the above is all that is needed.
> I think the above covers what is really needed for AOP - and
> we already have it.  Just simpler syntax is needed IMO.  No
> extra baggage needs to be added to the class data structures.
>
> I'm not sure why you guys made such a lengthy RCR.  I think I
> have the concept now, but with all of the verbosity, it makes
> it difficult to figure out what you are really proposing.  I
> think a much more concise RCR would have been better.

The reason for cuts, for naming them, and the rest of the RCR, is simply 
because any other way proposed (using closures as above, and already shown 
in the past by Ara I think, or using method aliasing, and so on) makes it 
very hard to manage the stack of methods. Cuts give you the handle to do 
so. If you want the set of methods you've added, you can just grab the cut 
and you've got them.

We've been over all these things before in our discussions, including what 
you mention above, and none of it works well with Ruby's dynamic nature. 
Because cuts are based in inheritance, it does work with Ruby's dynamic 
nature.

Peter