On Tue, Apr 19, 2005 at 02:02:41PM +0000, Ingo Blechschmidt wrote:
: Hi,  
: quoting an old post from Luke (http://xrl.us/ftet): 
: > C<tie>ing is going to work quite differently, from what I hear.  
: > So it might be possible to overload any function to call a  
: > special version when your type of array is used.  You just have  
: > to write all the special versions.  
: So is the following valid?  
:   class TiedArray is Array {  
:     method push([EMAIL PROTECTED]) {  
:       ...;  
:     }  
:   }  
:   my TiedArray @array;  
:   push @array:    ...; # calls our push  
:   unshift @array: ...; # calls Array::unshift  
:   # Will push @array, ... DWIM?  

That doesn't quite work the way you have it.  You've used the syntax
for declaring the types of the individual elements of your array,
equivalent to

    my @array is Array of TiedArray;  

Instead, you want:

    my @array is TiedArray;  

: How do I define the method/sub responsible for @array.[index]/  
: %hash.{key}?  
:   class TiedArray is Array {  
:     # Possibility #1  
:     method *postcircumfix:<'[', ']'>(TiedArray $self, $index) {  
:       return new Proxy:  
:         FETCH => {...},  
:         STORE => {...};  
:     }  
:     # Possibility #2  
:     multi sub *postcircumfix:<'[', ']'>(TiedArray $self, $index) {  
:       # Body as above  
:     }  
:     # Possibility #3  
:     method FETCH($index)       {...}  
:     method STORE($index, $val) {...}  
:     # Possibility #4  
:     method GET($index) is rw {  
:       # Body as in possibility #1  
:     }  
:   }  
: FWIW, I like possibility #4 best.  

None of those are quite right, because you have to be prepared to deal
not only with slices, but with multiple dimensions of slices.

But to answer your question, #1 is probably the closest to what is
actually going on under the covers, though it needs an "is rw" if you
want to be able to assign to your slice.  However, I don't doubt that
someone will come up with various kinds of syntactic sugar to paper
over the lvalue/rvalue proxying system, which is designed to keep the
identification operations distinct from the getter/setter operations.
It's not designed to make people happy who want to confuse those
issues.  We have macros for that.

That's the philosophy, anyway.  It may yet turn out that proxying
completely fouls up the optimizer in this case.  Sometimes a
cut-and-paste has the benefit of being concrete enough for the
optimizer to understand, whereas the abstraction is too, er, abstract.
If the rw method can just pass the raw slice information off to its
FETCH and STORE, it's probably a wash.  If it has to generate a new
data structure to pass, that gets more expensive, and is likely to
be slower than merely duplicating the code that defines the identity
operationally rather than in a data structure.  However, that being
said, there's enough flexibility in the FETCH/STORE proxy that you
could "defactor" the identification code out to the various handlers
and get the same benefit.  A syntactic sugar solution like #4 might
do just that.

If the proxy generating method does nothing but pass its input off
to the handlers, then we have the case that the object can serve as
its own proxy, in which case you could probably define the FETCH and
STORE directly in the class, much like your #3.  However, we'd have
to deal with the fact that the proxy's FETCH and STORE are relying
on lexical scoping to get the slicing info into their closures,
while #3's FETCH and STORE are getting that info via direct parameters.
So we can't just freely interconvert those.

Is that enough muddy thinking for one morning?


Reply via email to