in reply to Is tie inteded to be used in this way?

First i have a question not explicitatedd in the original node, about the clearing routine: if i modify my trigger function to manage undef values as in
sub trigger{print "Triggered: ",map {defined $_ ? " $_" : 'UNDEF'}@_," +\n"}
When i try to @arr=undef the tie'magic is called twice. Why?
# rest of the code as before.. print "\tclearing with undef \@arr:\n" and undef @arr; print "\tSetting list:\n" and @arr = qw(a); print "\tclearing with \@arr=undef:\n" and @arr=undef; print "\tSetting list:\n" and @arr = qw(a); print "\tclearing with \@arr=():\n" and @arr=(); __OUT__ clearing with undef @arr: Triggered: Arraytrigger=ARRAY(0x6ab224) Setting list: Triggered: Arraytrigger=ARRAY(0x6ab224) Triggered: Arraytrigger=ARRAY(0x6ab224) 0 a clearing with @arr=undef: Triggered: Arraytrigger=ARRAY(0x6ab224) Triggered: Arraytrigger=ARRAY(0x6ab224) 0UNDEF Setting list: Triggered: Arraytrigger=ARRAY(0x6ab224) Triggered: Arraytrigger=ARRAY(0x6ab224) 0 a clearing with @arr=(): Triggered: Arraytrigger=ARRAY(0x6ab224)
Second question: why the code is not triggered when i do a reference to some tied array's elements?
my $ref = \$arr[0]; print "\tsetting by reference:\n" and $ref=11; __OUT__ setting by reference:
Third and more important, why i'm no more able to print my array? nor dump or dd it? a simply
print "\@arr [@arr]\n";
put before clearing the array simply make my program hang, while eating lot of memory in with my Strawberry perl 5.14.2?

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re^2: Is tie inteded to be used in this way? Few question arise
by choroba (Cardinal) on Apr 28, 2015 at 22:18 UTC
    1. @arr = undef;

      is not the same as

      undef @arr;

      It assigns undef to the first element of the array, i.e. it's equivalent to

      @arr = (undef);

      Therefore, it calls CLEAR and STORE, which means two trigger calls.

    2. If you store \$arr[0] in a $ref, then assigning $ref = 11 you just remove the reference from $ref. You have to assign to where it points to trigger the magic:
      $$ref = 11;
    3. You probably still do
      $self->SUPER::STORE($self, @_);

      Remove the $self from the arguments and the problem is gone.

      Update: Here's what caused the problem: when a reference is used as a number, it returns its "address" (which is good for comparing references with ==). Therefore, when you supplied $self as the first argument to STORE, it was interpreted as the index where the actual index was stored. The number was probably very high, so the array become gargantuan.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      thanks but even if the code below runs well with all your improvements, as soon as i add a simply print "\@arr [@arr]\n"; at the end, the program hangs, eating a lot of memory. I dont understand why.
      use strict; use warnings; sub trigger{print "Triggered: ",map {defined $_ ? " $_" : 'UNDEF'}@_," +\n"} { package Arraytrigger; use Tie::Array; use vars qw(@ISA); @ISA = ('Tie::StdArray'); for (qw(STORE CLEAR PUSH POP SHIFT UNSHIFT)) { my $s = "SUPER::$_"; no strict 'refs'; *$_ = sub { &main::trigger; shift()->$s(\@_) }; } } #package main.. tie my @arr, 'Arraytrigger'; print "\tSetting list:\n" and @arr = qw(a b c d e); #print "\tSetting one:\n" and $arr[0]=0; #print "\tpushing:\n" and push @arr,'f'; #print "\tpopping:\n" and pop @arr; #print "\tshifting:\n" and shift @arr; #print "\tunshifting:\n" and unshift @arr, 'zero'; #print "\tclearing with undef \@arr:\n" and undef @arr; #print "\tSetting list:\n" and @arr = qw(a); #print "\tSetting list:\n" and @arr = qw(a); #print "\tclearing with \@arr=():\n" and @arr=(); #my $ref = \$arr[0]; #print "\tsetting by reference:\n" and $$ref=11; #print "\tclearing:\n" and @arr=();#undef @arr and @arr=undef se +em no good..e # print "\@arr [@arr]\n"; #use Data::Dump;print dd(@arr);
      thanks
      L*
      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        My mistake. The \ before @_ was there because of double quotes, so it should've been removed:
        *$_ = sub { &main::trigger; shift()->$s(@_) };
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      thanks choroba,
      1 and 2 ... prove that is not wise to code when you have fever above 38.. i'll try to remember.
      3. thanks, now i understand

      L*
      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.