Using map to assign var values from hash

  • Thread starter Richard A. DeVenezia
  • Start date
R

Richard A. DeVenezia

This doesn't assign variables. Then commented out 'eval join' version does.
Why doesn't the first version work ?

#!perl -w
use strict;

doStuff (a=>1, b=>2, c=>'foo', foo=>'bar', z=>9);

sub doStuff {
my %param = @_;
my ($a, $b, $c);
my @allowed = qw (a b c);

no strict 'refs';
map $$_ = $param{$_}, @allowed;
use strict;

# eval join ("", map "\$$_ = \$param{'$_'};", @allowed);

print "a=$a\nb=$b\nc=$c\n";
}
 
W

Wolfgang Fischer

This doesn't assign variables. Then commented out 'eval join' version does.
Why doesn't the first version work ?

#!perl -w
use strict;

doStuff (a=>1, b=>2, c=>'foo', foo=>'bar', z=>9);

sub doStuff {
my %param = @_;
my ($a, $b, $c);
my @allowed = qw (a b c);

no strict 'refs';
map $$_ = $param{$_}, @allowed;
Hello,
you can't use variables like $$_; You have to specify the variable name
at compile time, not at run time.
use strict;

# eval join ("", map "\$$_ = \$param{'$_'};", @allowed);
This creates and evals the string
"$a=$param{'a'};$b=$param{'b'};$c=$param{'c'};"
So eval doesn't get something like $$_=.... But why don't you use
this?
my($a,$b,$c)=($param{'a'},$param{'b'},$param{'c'});
 
J

Jay Tilton

: On Sun, 12 Oct 2003 04:42:53 -0400, Richard A. DeVenezia wrote:
:
: > This doesn't assign variables. Then commented out 'eval join' version does.
: > Why doesn't the first version work ?
: >
: > #!perl -w
: > use strict;
: >
: > doStuff (a=>1, b=>2, c=>'foo', foo=>'bar', z=>9);
: >
: > sub doStuff {
: > my %param = @_;
: > my ($a, $b, $c);
: > my @allowed = qw (a b c);
: >
: > no strict 'refs';
: > map $$_ = $param{$_}, @allowed;
:
: you can't use variables like $$_;

Sure you can.

: You have to specify the variable name
: at compile time, not at run time.

Not true at all.

What the OP is trying to do is to assign a value to a scalar by symbolic
reference. It's working, but on the package variables $::a, $::b, and
$::c, not the lexically declared $a, $b and $c he expects.

: But why don't you use
: this?
: my($a,$b,$c)=($param{'a'},$param{'b'},$param{'c'});

Solid advice. Or even,

my($a, $b, $c) = @param{qw/a b c/};
 
G

Greg Bacon

: This doesn't assign variables. Then commented out 'eval join' version
: does. Why doesn't the first version work ?
: [...]

Symbolic references point to globals, not lexicals, but declaring $a,
$b, and $c as lexicals in that scope made a little more work necessary
to get at the globals. Look at the globals after your assignment:

#! /usr/local/bin/perl

use warnings;
use strict;

our($a,$b,$c);

doStuff (a=>1, b=>2, c=>'foo', foo=>'bar', z=>9);

sub doStuff {
my %param = @_;
# my ($a, $b, $c);
my @allowed = qw (a b c);

no strict 'refs';
map $$_ = $param{$_}, @allowed;
use strict;

# eval join ("", map "\$$_ = \$param{'$_'};", @allowed);

print "a=$a\nb=$b\nc=$c\n";
}

Hope this helps,
Greg
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sun, 12 Oct 2003 04:42:53 -0400, Richard A. DeVenezia wrote:

Hello,
you can't use variables like $$_; You have to specify the variable
name at compile time, not at run time.

Please do not post answers to questions unless you know what you're talking
about. One most certainly can specify variable names at runtime. $$_ is
perfectly valid Perl.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP4lhOmPeouIeTNHoEQLJ5gCcCypVbYabgVI/h9708V412VbAUhAAoNTo
Jq8LkmwsOPzR8iGIfrigG07A
=wYlV
-----END PGP SIGNATURE-----
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This doesn't assign variables. Then commented out 'eval join' version
does. Why doesn't the first version work ?

#!perl -w
use strict;

doStuff (a=>1, b=>2, c=>'foo', foo=>'bar', z=>9);

sub doStuff {
my %param = @_;
my ($a, $b, $c);
my @allowed = qw (a b c);

no strict 'refs';
map $$_ = $param{$_}, @allowed;
use strict;

# eval join ("", map "\$$_ = \$param{'$_'};", @allowed);

print "a=$a\nb=$b\nc=$c\n";
}

Jay Tilton and Greg Bacon have already pointed out what's going on here,
so I won't repeat what they said.

However, a word of style: Why not leave the caller's value assignments in
a hash, instead of polluting the global variable space? Something like:

$caller_options{$_} = $param{$_} for @allowed;

Without knowing the big picture of what you're doing, I can't say if this
is better than assigning global variables or not. But it's a thought.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP4lieWPeouIeTNHoEQKsIwCgmZFNxSr/lGy0kLbInmGU4SBFz7YAnjCU
Bs9KTxiWvjPLznNEvoOBxprk
=k07R
-----END PGP SIGNATURE-----
 
M

Malcolm Dew-Jones

Eric J. Roode ([email protected]) wrote:

: > you can't use variables like $$_; You have to specify the variable
: > name at compile time, not at run time.

: Please do not post answers to questions unless you know what you're talking
: about.

I think we can safely assume that he thought he knew what he was talking
about, so your advice wouldn't have made any difference.
 
A

Anno Siegel

Malcolm Dew-Jones said:
Eric J. Roode ([email protected]) wrote:

: > you can't use variables like $$_; You have to specify the variable
: > name at compile time, not at run time.

: Please do not post answers to questions unless you know what you're talking
: about.

I think we can safely assume that he thought he knew what he was talking
about, so your advice wouldn't have made any difference.

Wouldn't have, in the past. It may make a difference in the future.

Anno
 
T

Tassilo v. Parseval

Also sprach Anno Siegel:
Wouldn't have, in the past. It may make a difference in the future.

But it's not required. People shouldn't deliberately state wrong things,
but then they shouldn't be forced to double-check that their given
advice is 100% correct either. Their mistake is going to be pointed out
to them which is a good way of learning. In my first year in this group
I learnt the most by being corrected.

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top