If perl is invocation by reference, why is this happening?
I read that perl uses call-by-reference when executing routines. I made a simple piece of code to test this property, but it behaves as if perl was the default:
$x=50;
$y=70;
sub interchange {
($x1, $y1) = @_;
$z1 = $x1;
$x1 = $y1;
$y1 = $z1;
print "x1:$x1 y1:$y1\n";
}
&interchange ($x, $y);
print "x:$x y:$y\n";
This leads to the following output:
$ perl example.pl
x1:70 y1:50
x:50 y:70
If the arguments were processed by a callback method, shouldn't x be equal to x1 and y equal to y1?
source to share
To change values ββoutside of sub, you will need to change the values @_
.
The following sub interchange
makes the values ββchange:
sub interchange {
($x1, $y1) = @_; # this line copies the values to 2 new variables
$z1 = $x1;
$x1 = $y1;
$y1 = $z1;
$_[0] = $x1; # this line added to change value outside sub
$_[1] = $y1; # this line added to change value outside sub
print "x1:$x1 y1:$y1\n";
}
This gives the result:
x1:70 y1:50
x:70 y:50
More information here: http://www.cs.cf.ac.uk/Dave/PERL/node51.html
But, quoting the article:
You can see that the function may have affected the @array variable in the main program. This is generally considered bad programming practice because it does not isolate what the function does from the rest of the program.
source to share
Perl is always definitely referenced by reference. You are declaring ($x1, $y1) = @_
copying the original argument values, since @_ contains aliases to the original parameters.
From the perlsub manpage:
Any arguments passed are displayed in the @_ array. Therefore, if you call a function with two arguments, they will be stored in $ [0] and $ [1]. The @_ array is a local array, but its elements are aliases for real scalar parameters. In particular, if the $ _ [0] element is updated, the corresponding argument is updated (or an error is raised if it is not updatable).
source to share
I'm just getting started with Perl, and I believe you are misunderstanding what you are passing to a subroutine. When you pass $ x and $ y, you are passing the scalars $ x and $ y. You need to explicitly pass a reference that is also a scalar (the only thing ever allowed to pass to subroutines). I understand where you came from thinking that this is a call by reference, as for arrays and hashes, as you need to pass references to them.
This code should do what you are looking for:
#!/usr/bin/perl
$x=50;
$y=70;
sub interchange {
($x1, $y1) = @_;
$z1 = $$x1; # Dereferencing $x1
$$x1 = $$y1; # Dereferencing $x1 and $y1
$$y1 = $z1; # Dereferencing $y1
print "x1:$$x1 y1:$$y1\n";
}
&interchange (\$x, \$y); # Passing references to $x and $y, not their values
print "x:$x y:$y\n";
I am passing references to $ x and $ y using \ $ x and \ $ y. Then I use $$ x and $$ y to dereference them inside the subroutine.
source to share