assignments of arrays

T

Toralf Förster

In the following program I'd expect that line 29 fills @Values with zeros, but for i==2 this is counterproofed.

Why ?

$ nl -ba zero.pl
1 #!/usr/bin/perl
2
3 # Toralf Förster
4 # Hamburg
5 # Germany
6
7 use strict;
8 use diagnostics;
9 $diagnostics::pRETTY = 1;
10
11 use warnings FATAL => 'uninitialized';
12 use Carp ();
13 $SIG{__DIE__} = \&Carp::confess;
14
15
16 my $Cols = 30;
17 my $Rows = 16;
18
19 my @Zero = ();
20 foreach my $r (0..$Rows+1) {
21 foreach my $c (0..$Cols+1) {
22 $Zero[$r][$c] = 0;
23 }
24 }
25
26 my $N = 10;
27 foreach my $i (1..$N) {
28
29 my @Values = @Zero;
30
31 foreach my $r (0..$Rows+1) {
32 foreach my $c (0..$Cols+1) {
33 if ($Values[$r][$c] != 0) {
34 die "i=$i\tr=$r\tc=$c\t$Values[$r][$c]\n";
35 }
36 }
37 }
38
39 foreach my $r (0..$Rows+1) {
40 foreach my $c (0..$Cols+1) {
41 $Values[$r][$c] = 1;
42 }
43 }
44 }
45
46
47 exit (0);
48


tfoerste@n22 ~/workspace/misc $ ./zero.pl
i=2 r=0 c=0 1
at ./zero.pl line 34
 
G

George Mpouras

Be carefull Toralf Förster.
At your statement my @Values = @Zero;
you are "playing" with array references.
So when you fill the @Values with 1 what you are doing is at the same time
to fill the @Zero with 1
what you must do , to have what you mean is the following:
George Bouras
Athens, Greece


....

my $N = 10;
foreach my $i (1..$N)
{
my @Values = ();

for (my $i=0;$i<=$#Zero;$i++)
{
for (my $j=0;$j<=$#{$Zero[$i]};$j++)
{
$Values[$i][$j] = $Zero[$i][$j]
}

}

foreach my $r (0..$Rows+1)
{
foreach my $c (0..$Cols+1)
{
print "i=$i\tr=$r\tc=$c\t$Values[$r][$c]\n";
if ($Values[$r][$c] != 0) { die
"i=$i\tr=$r\tc=$c\t$Values[$r][$c]\n"; }
}


}

foreach my $r (0..$Rows+1) {
foreach my $c (0..$Cols+1) {
$Values[$r][$c] = 1 } }
}

exit 0;
 
G

George Mpouras

Henry, try to avoid the hardcoded values of $Rows and $Cols by using the
array offsets !


Ο "Henry Law" έγÏαψε στο μήνυμα
 
T

Toralf Förster

you are "playing" with array references.
So when you fill the @Values with 1 what you are doing is at the same
time to fill the @Zero with 1

ick

@all
thx for the explanation
 
C

C.DeRykus

An easier way to do this is to use the Clone module:



use Clone "clone";



my @Values = map clone($_), @Zero;

# or

my @Values = @{ clone \@Zero };

Alternatively: Storable's dclone:

use Storable qw/dclone/;
@Values = @{ dclone \@Zero };

Storable is core which is a plus but I notice the docs mention:

"Clone is faster for data structures with 3 or less levels,
while dclone() can be faster for structures 4 or more levels deep."
 
T

Toralf Förster

At your statement my @Values = @Zero;
you are "playing" with array references.

OTOH this was so clear for me b/c if I pass parameters to a sub like foo
(@Values) then this means a call-by-value whereas foo (\@Values) passes
just the reference to the sub called "foo".
 
P

Peter J. Holzer

OTOH this was so clear for me b/c if I pass parameters to a sub like foo
(@Values) then this means a call-by-value

No.

Parameters are passed by reference in Perl.

For example, consider this code:

sub foo {
$_[1] = 5;
}

my @x = (1, 2, 3);
foo(@x);
print "@x\n";

my ($x, $y, $z) = qw(a b c);
foo($x, $y, $z);
print "$x $y $z\n";
__END__

It prints
1 5 3
a 5 c
which clearly shows that the array @x and the variably $y were passed by
reference (in Perl jargon, we call this "aliasing", but it's the same
concept).

What creates the *illusion* that Perl function calls are by value is the
convention to immediately assign parameters to local variables. So you
would normally write foo as

sub foo {
my @p = @_;
$p[1] = 5;
}

or

sub foo {
my ($p1, $p2, $p3) = @_;
$p2 = 5;
}

Here the assignments in the second line alter only the local variable
(@p or $p2, respectively), not the parameters. But it's the assignment
in the first line which causes the values to be copied, not the function
call.

hp
 
T

Toralf Förster

What creates the *illusion* that Perl function calls are by value is the
convention to immediately assign parameters to local variables. So you
would normally write foo as ....
Here the assignments in the second line alter only the local variable
(@p or $p2, respectively), not the parameters. But it's the assignment
in the first line which causes the values to be copied, not the function
call.

hp

ah - now I did understood it much better
Thx for this answer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top