Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a scalar reference in Perl

I know that passing a scalar to a sub is actually passing the reference, but since I am new to perl I still did the following test:

#!/usr/bin/perl
$i = 2;
subr(\$i);
sub subr{
    print $_[0]."\n";
    print $$_[0]."\n";
}

I thought the first line is going to print an address and the second line is going to give be back the number, but the second one is a blank line. I was pointed by someone one else to do this: ${$_[0]} and it prints the number. But she didn't know the reason why without {} it is not working and why it is working with {}. So what has happened?

like image 862
user685275 Avatar asked May 03 '11 15:05

user685275


2 Answers

It's because your second print statement is equivalent to doing this...

my $x = $$_; print $x[0];

When what you want is

my $x = $_[0]; print $$x;

In other words, the de-referencing occurs before the array subscript is evaluated.

When you add those curl-wurlies, it tells perl how to interpret the expression as you want it; it will evaluate $_[0] first, and then de-reference to get the value.

like image 73
Ed Guiness Avatar answered Sep 30 '22 19:09

Ed Guiness


It's an order-of-evaluation thing.

  $$_[0] is evaluated as {$$_}[0]

This is the 0th element of the reference of the scalar variable $_. It's taking the reference first and then trying to find the 0th element of it.

  ${$_[0]}

This is a reference to the 0th element of the array @_. It's finding the 0th element first then taking a reference of that.

If you set use strict and use warnings at the top of your code you'll see plenty of warnings about undefined values from your first attempt.

like image 24
bot403 Avatar answered Sep 30 '22 19:09

bot403