http://qs321.pair.com?node_id=430608


in reply to Adding scalars but with a twist..

If you want to go a step farther than eval, you can use some tie magic to "shadow" the original $Sel1Ttl variables with a real array.

You have to be careful about how you index into this array -- $Sel1Ttl counts up from one, but (modern) Perl arrays count up from zero. In this code, I put a dummy element at index zero so that $a1z = $az[1].

#!/usr/bin/perl -w use strict; { package FixedArrayOfScalarRefs; use Carp qw( croak ); sub TIEARRAY { my ( $class, @refs ) = @_; my $self = [@refs]; bless $self, $class; return $self; } sub FETCH { my ( $self, $index ) = @_; if ( not ref $self->[$index] ) { croak "Array index $index out-of-bounds"; } my $value = ${ $self->[$index] }; return $value; } sub STORE { my ( $self, $index, $value ) = @_; if ( not ref $self->[$index] ) { croak "Array index $index out-of-bounds"; } ${ $self->[$index] } = $value; } sub FETCHSIZE { my ($self) = @_; return scalar @$self; } }
my ( $a1z, $a2z, $a3z ) = qw( 42 13 666 ); my @az; tie @az, 'FixedArrayOfScalarRefs', "There is no element zero!", # Dummy element 0 \( $a1z, $a2z, $a3z ); # Elements 1 .. 3 for ( 1 .. 3 ) { print "\$a${_}z = $az[$_]\n"; }

Since the dummy element zero is not a reference, the tied array will croak if you accidentally use it:

print "\$a0z = $az[0]\n"; # Array index 0 out-of-bounds at bar.pl line 63

With the array, you can use the traditional for (1 .. 3) { $sum += $az[$_] } or the IMHO prettier:

use List::Util qw( sum ); my $sum = sum( @az[ 1 .. 3 ] ); print "sum = $sum\n";

If you'd prefer $Sel1Ttl = $SelTtl[0], leave out the dummy element in the tie. If you do, the sum becomes:

my $sum = sum( @az );