I came across this syntax while reading a script. I am not sure what is the use of square brackets.
push @data, [ split //, $line ]; #printing this array gives crap values
Or to put into other words what is the difference between the above and the following?
push @data, (split//, $line); #printing this gives actual values
Any suggestions?
[] creates an array reference. [ $scalar, $scalar ] creates an array reference with two items in it. short($file) calls a subroutine and returns something (probably a scalar or a list of scalars)
[ ] Anything shown enclosed within square brackets is optional unless indicated otherwise. The square brackets themselves are not typed unless they are shown in bold. | A vertical bar that separates two or more elements indicates that any one of the elements can be typed.
Square brackets are used to index (access) elements in arrays and also Strings. Specifically lost[i] will evaluate to the ith item in the array named lost.
Putting the element index in parentheses (or brackets in this case) after an array is called “subscripting”. The index is called a “subscript”. There is no special name for directly subscripting the array returned by a message without storing the array in a variable first.
The code:
push @data, (split//, $line);
pushes all items on the current line into @data
and
push @data, [split //, $line];
Pushes a reference to an anonymous array containing those items into @data
If you're only ever processing one value of '$line' its probably more effective to use the former*1 , however, if you are processing a file that contains multiple lines and you want to differentiate between the lines the content is on, the latter is more effective.
Consider:
my @data;
while( my $line = <$fh> ){
push @data , ( split //, $line );
}
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
print Dumper( \@data );
This will yield all of the bytes read in as separate characters, a single array containing them all, i.e.:
[ "a", "b" , "c" , "\n", "d", "e", "f" ]
When this instead will do something entirely different:
my @data;
while( my $line = <$fh> ){
push @data , [ split //, $line ];
}
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
print Dumper( \@data );
And will instead group lines like so:
[ [ "a", "b", "c" , "\n" ], [ "d" , "e", "f" , "\n" ] ]
So you can later programmatically traverse it easier.
push @data, ( split //, $line );
and
push @data, split //, $line;
Are equivalent.
Also,
my @other = ( 1,2,3 );
push @data, @other ;
and
push @data, 1,2,3;
are equivalent.
From perldoc -f push
push ARRAY,LIST Treats ARRAY as a stack, and pushes the values of LIST onto the end of ARRAY. The length of ARRAY increases by the length of LIST. Has the same effect as for $value (LIST) { $ARRAY[++$#ARRAY] = $value; } but is more efficient. Returns the number of elements in the array following the completed "push".
*1: actually, tbf, anyone with half a brain would probably want @data = split //, $line
That is from one of my answers:
push @data, [ split //, $line ];
@data
is an array of array refs. Each element of @data
is a reference to an anonymous array whose entries are the characters in $line
.
See also perldoc perlreftut.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With