Using map to assign var values from hash

Discussion in 'Perl Misc' started by Richard A. DeVenezia, Oct 12, 2003.

  1. 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";
    }

    --
    Richard
    Richard A. DeVenezia, Oct 12, 2003
    #1
    1. Advertising

  2. 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;

    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'});
    >
    > print "a=$a\nb=$b\nc=$c\n";
    > }
    Wolfgang Fischer, Oct 12, 2003
    #2
    1. Advertising

  3. Richard A. DeVenezia

    Jay Tilton Guest

    Wolfgang Fischer <> wrote:

    : 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/};
    Jay Tilton, Oct 12, 2003
    #3
  4. Richard A. DeVenezia

    Greg Bacon Guest

    In article <bmb475$kr5ja$-berlin.de>,
    Richard A. DeVenezia <> wrote:

    : 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
    --
    . . . this one single rule, rationally construed and applied, is enough to
    form the starting point of all that is necessary in government: to make no
    more laws than those useful for preventing a man or body of men from
    infringing on the rights of other men. -- Walt Whitman, "Government"
    Greg Bacon, Oct 12, 2003
    #4
  5. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Wolfgang Fischer <> wrote in
    news:p:

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


    >> 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.


    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-----
    Eric J. Roode, Oct 12, 2003
    #5
  6. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    "Richard A. DeVenezia" <> wrote in
    news:bmb475$kr5ja$-berlin.de:

    > 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-----
    Eric J. Roode, Oct 12, 2003
    #6
  7. Eric J. Roode () wrote:
    : Wolfgang Fischer <> wrote in

    : > 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.
    Malcolm Dew-Jones, Oct 12, 2003
    #7
  8. Richard A. DeVenezia

    Anno Siegel Guest

    Malcolm Dew-Jones <> wrote in comp.lang.perl.misc:
    > Eric J. Roode () wrote:
    > : Wolfgang Fischer <> wrote in
    >
    > : > 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
    Anno Siegel, Oct 13, 2003
    #8
  9. Also sprach Anno Siegel:

    > Malcolm Dew-Jones <> wrote in comp.lang.perl.misc:
    >> Eric J. Roode () wrote:
    >> : 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.


    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
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
    Tassilo v. Parseval, Oct 13, 2003
    #9
  10. Thanks for all the great advice,
    I went with Jay's suggestion.

    --
    Richard
    Richard A. DeVenezia, Oct 14, 2003
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. navS
    Replies:
    3
    Views:
    491
    Ismo Salonen
    May 9, 2008
  2. rp
    Replies:
    1
    Views:
    493
    red floyd
    Nov 10, 2011
  3. Une bévue
    Replies:
    5
    Views:
    140
    Une bévue
    Aug 10, 2006
  4. kenneth
    Replies:
    1
    Views:
    113
    Gunnar Hjalmarsson
    Dec 11, 2004
  5. prati
    Replies:
    0
    Views:
    422
    prati
    Oct 27, 2012
Loading...

Share This Page