views:

560

answers:

4

Simple question:

How do I do this on one line:

my $foo = $bar->{baz};
fizz(\$foo);

I've tried \$bar->{baz}, \${$bar->{baz}}, and numerous others. Is this even possible?

-fREW

Update: Ok, the hashref is coming from DBI and I am passing the scalar ref into template toolkit. I guess now that I look more closely the issue is something to do with how TT does all of this. Effectively I want to say:

$template->process(\$row->{body}, $data);

But TT doesn't work that way, TT takes a scalar ref and puts the data there, so I'd have to do this:

$template->process(\$row->{body}, $shopdata, \$row->{data});

Anyway, thanks for the help. I'll at least only have one reference instead of two.

A: 

I am not even sure what you are doing. You also should put quotes around baz.

Now let's consider that you assign a scalar to the scalar in the first line then the second line should work. However I don't really know if this is what you are trying here and it does not really make sense in Perl. Using references is often used in other languages to

  1. speed up a function call
  2. allow multiple values to be returned.

Now the first is usually not needed with scalars and anyway Perl is a script language so if you are really concerned about speed write C.

The second is not needed in Perl as you can return lists and references to anonymous hashes quite easy.

Have you looked at "man perlref"?

Ralf
There's no reason to put quotes around baz. Perl autoquotes hash keys if they consist entirely of \w characters.
runrig
Also, passing scalar references is useful in, e.g., bioinformatics where you may want to avoid making copies of large amounts of data.
runrig
+2  A: 

You didn't show how %bar and fizz() were setup, so I set them up like this:

my %hash;
my $bar = \%hash;
$hash{baz} = "found it\n";
sub fizz {
  my $ref = shift;
  print $$ref;
}

Then, both of these work, your orignal:

my $foo = $bar->{baz};
fizz(\$foo);

and one of the variants you said you tried:

fizz(\$bar->{baz});

Can you show the error that's giving you?

jimtut
+5  A: 
\$bar->{baz}

should work.

E.g.:

my $foo;
$foo->{bar} = 123;

my $bar = \$foo->{bar};

$$bar = 456;

print "$foo->{bar}\n";   # prints "456"

In answer to the update in the OP, you can do:

\@$row{qw(body data)};

This is not the same as \@array, which would create one reference to an array. The above will distribute the reference and make a list of two references.

runrig
+4  A: 

\$bar->{baz} seems to do the trick for me:

my $bar = { baz => 1 };
print $bar->{baz}, "\n";  # prints 1
my $ref =  \$bar->{baz};
print $$ref, "\n";        # prints 1
$$ref = 2;
print $bar->{baz}, "\n";  # prints 2
Yanick