in reply to Re^2: index wrapping in tied FETCH and EXISTS
in thread index wrapping in tied FETCH and EXISTS

To me your test shows that you CAN'T reach lower than the start of the array by using an index lower than -@array. A return value of undef is the only way that perl has to tell you that you're doing something bad. OK, not the only way, but dieing/croaking seems too strong for an out-of-range array index.

It occurred since my previous note that I shouldn't emulate this behavior in the direct-call routines that underlie my tied arrays, because then a user of a tied array would be faced with two layers of "wrapping around".

Unless I can figure out how to differentiate a tied call from a direct one. Since tied calls come through a little "dereference wrapper" from my AUTOLOAD routine (its PM thread ended yesterday), this should be possible, but I'm not sure it's worth the overhead.

cmac
www.animalhead.com

Replies are listed 'Best First'.
Re^4: index wrapping in tied FETCH and EXISTS
by ikegami (Patriarch) on Feb 04, 2009 at 20:43 UTC

    To me your test shows that you CAN'T reach lower than the start of the array

    I'd love to see what's your definition "can" in this situation. Let's say you're right and you can't reach before the start of the array. What would be returned if you could?

    To me, "can" would be returning what's at that location. It correctly returns undef.

    Unless I can figure out how to differentiate a tied call from a direct one.

    sub FETCH { my ($self, $i) = @_; return $self->_fetch($i); } sub fetch { my ($self, $i) = @_; $i += $self->num_eles() if $i < 0; return undef if $i < 0; return $self->_fetch($i); } sub _fetch { my ($self, $i) = @_; # $i is guaranteed to be in range ... }
      Thank you, mr. i!

      In my case this technique involved making the AUTOLOAD routine tag the array routine names (to which tie calls go) with "_nowrap", and modifying the XS linkage routines like this:
      SV * abc_array_fetch (array, index) abc_array *array IV index ALIAS: abca_array_fetch=1 abc_array_fetch_nowrap=2 abca_array_fetch_nowrap=3 CODE: if (index < 0 && !(ix & 2)) index += array->entries; RETVAL = abc_array_fetch (array, index, ix&1);
      The best part is, it seems to work.

      Thanks again,
      cmac
      www.animalhead.com