David Nicol wrote:

> On 12/10/05, $Bill Luebkert <[EMAIL PROTECTED]> wrote:
> 
>>The fact that you can modify the vrbl passed to a sub from in the sub without
>>using a reference still doesn't mean that it's passed by reference.
> 
> No. You  are mistaken. That is exactly what passing by reference means.

In Perl a reference is created using this syntax (there are other alternate
ways to create a reference, but that's the normal way) : \$var

If you didn't use that syntax, it's not a reference.  So we have a syntactical
disagreement.  Just because you can use a vrbl like a reference doesn't make it
one (in the Perl sense).  We're talking Perl references here.

> Example:
>     sub Increment($){ $_[0]++ };
> 
> If you want to protect your passed arguments from possible modification,
> make a copy of them before submitting them:
> 
> my @args=($SomeVariable);
> &Increment(@args);  # $SomeVariable will not be touched

You're still confusing the fact that an target argument can be modified
with the fact that a vrbl is a reference or not.  Because you can modify
a vrbl indirectly through an argument name doesn't make it a true Perl
reference.  This is just some special aliasing logic that allows this to
work in a sub.  What's passed is the value rather than a reference to the
value.  All you have to do to prove that is print it:

my $one = 1;
mysub ($one);           # prints '1'
mysub (\$one);          # prints 'SCALAR(0x23bd88)'
sub mysub { print "@_\n"; }

You have to speak in Perl terms rather than what you think of in non-Perl
terms - a reference is a very specific animal in Perl.

> You could even write a byvalue wrapper if you want, something like
> 
> sub ByValue(\&;){
>     my $coderef = shift;
>     my @argvals = @_;  # copying arg refs to new array, by value, or
> at least COW
>     &$coderef(@argvals);
> };

That's not necessary - just shift the args into local vrbls and
you have the same thing - why complicate it.  Quit thinking in terms
of basic and think in terms of Perl.

my $var = 1;
whatever ($one);

sub whatever {
        my $local_var = shift;
or
        my $local_var = $_[0];
<do stuff to $local_var and it doesn't modify the orig $var>
}

You can specifically test for a reference in a sub and handle both cases
as we showed earlier I believe.

my $one = 1;
mysub ($one);
mysub (\$one);

sub mysub {
        my $var = shift;

if (ref $var) {
        print "$$var\n";
} else {
        print "$var\n";
}

}

Now both calls will print '1'.

_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to