[pm-h] Binding variables to a reference

G. Wade Johnson gwadej at anomaly.org
Fri Dec 19 21:21:40 PST 2008


On Fri, 19 Dec 2008 23:01:18 -0600
"Todd Rinaldo" <toddr at null.net> wrote:

> This has been driving me crazy, so I have to ask how (and/or if) this
> can be done. I have the below program. If you run it, bar prints out.
> This exemplifies how you can alter the variables that were passed to a
> target subroutine. substr does this but I suspect it's more a result
> of magic C code than magic Perl code.

Interesting question.

> my $foo = 'foo';
> bar($foo);
> print "$foo\n";
> exit;
> 
> sub bar {
>    $_[0] = 'bar';
> }

This works because $_[0] is an 'alias' for $foo when it is called.
There are a few places in Perl code where we generate aliases, and this
is one of them.

> My question, How do I do something like this and get it to print out
> bar?
> 
> my $foo = 'foo';
> bar($foo);
> print "$foo\n";
> exit;
> 
> sub bar {
>    my \$bar = \$_[0];
>    $bar = 'bar';
> }

This does not quite work for a couple of reasons. The corrected version
would be.

sub bar {
    my $bar = \$_[0];
    $$bar = 'bar';
}

The variable $bar is a reference to the alias in $_[0]. We have to
dereference $bar to be able to assign to what it points to.

If you don't want the dereference, you can resort to one of the other
places that we can get aliases, but it generates an even uglier syntax.

sub baz {
   for my $baz ( $_[0] )
   {
       $baz = 'baz';
   }
}

We don't have the dereference, but now we've got a spurious for loop
that is just used to get the aliasing.

Normally, I just use the $_[0] syntax if I'm modifying the arguments to
a sub, it is sufficiently strange that someone running across it is
likely to pause and realize that something magical is happening,
instead of assuming that they know what is happening.

G. Wade
-- 
Computer language design is just like a stroll in the park.  Jurassic
Park, that is.                                           -- Larry Wall


More information about the Houston mailing list