Here's a test for side effects of an eval test on a tied array.
use warnings;
use strict;
package ArrayTellTale;
use base 'Tie::Array';
@ArrayTellTale::calls = ();
sub TIEARRAY { bless [], __PACKAGE__ }
sub FETCH {
push @ArrayTellTale::calls, 'FETCH';
return $_[0]->[$_[1]];
}
sub STORE {
push @ArrayTellTale::calls, 'STORE';
$_[0]->[$_[1]] = $_[2];
}
sub FETCHSIZE {
push @ArrayTellTale::calls, 'FETCHSIZE';
return scalar @{$_[0]};
}
sub STORESIZE {
push @ArrayTellTale::calls, 'STORESIZE';
}
package main;
use Test::More 'tests' => 6;
is_deeply( [ @ArrayTellTale::calls ], [],
'call log empty before tie' );
tie my @arr, 'ArrayTellTale';
is_deeply( [ @ArrayTellTale::calls ], [],
'call log empty after tie' );
@arr = ( 1, 2, 3 );
is_deeply( [ @ArrayTellTale::calls ],
[ 'STORESIZE', 'STORE', 'STORE', 'STORE' ],
'call log after assignment' );
@ArrayTellTale::calls = ();
my $ref_to_tied = \@arr;
is_deeply( [ @ArrayTellTale::calls ], [],
'call log empty before eval test' );
my $is_array = eval { @{$ref_to_tied}; 1 };
is_deeply( [ @ArrayTellTale::calls ], [],
'call log empty after eval test' );
ok( $is_array, 'tied array ref detected as array' );
It seems the reason nothing is called during the test is that it's happening in void context. If I give the array dereference a context in the eval, it has to make a call to the object.