How to retrieve a scalar name in a foreach loop

Discussion in 'Perl Misc' started by Eric Pement, Jul 8, 2003.

  1. Eric Pement

    Eric Pement Guest

    I have a question that's really bugging me. I've tried looking in the
    Perl FAQ, the Perl Cookbook, the White Camel, and the Perl How-to
    under words like scalars, variables, names, reference, and
    dereference. No luck. (Or if the answer was present, I didn't
    recognize it.)

    What I'd like to do is something like this, where foreach() is
    followed by a list of scalars:

    $v1 = "foo";
    $v2 = "bar";
    $v3 = "baz";
    foreach my $arg ($v1, $v2, $v3) {
    print "name: \\$arg, value: $arg\n";
    }

    Desired output:

    name: $v1, value: foo
    name: $v2, value: bar
    name: $v3, value: baz

    Obviously, \\$arg won't work, and I've tried 15 other constructions
    and ways of building the foreach loop, all without success. What's the
    ticket here? How do I retrieve the name of the variable instead of its
    value?

    Now I expect that someone will suggest that I build a hash and then
    run "foreach(sort keys %hash)" to retrieve name-value pairs. That's
    not perfectly workable for me. What I'm actually doing is debugging
    someone else's CGI script of several thousand uncommented lines, and
    at key points I need to access the simple scalars that are already
    present rather than rewriting everything. In point of fact, the
    application calls over a dozen perl scripts and setting files, and I
    don't have the time or the mandate to overhaul the entire script. What
    I need are some well-placed diagnostics which will be used today and
    erased tomorrow, and the answer to this question would really help.

    Thanks in advance.

    --
    Eric Pement
     
    Eric Pement, Jul 8, 2003
    #1
    1. Advertising

  2. Eric Pement

    Greg Bacon Guest

    In article <>,
    Eric Pement <> wrote:

    : $v1 = "foo";
    : $v2 = "bar";
    : $v3 = "baz";
    : foreach my $arg ($v1, $v2, $v3) {
    : print "name: \\$arg, value: $arg\n";
    : }
    :
    : Desired output:
    :
    : name: $v1, value: foo
    : name: $v2, value: bar
    : name: $v3, value: baz

    % cat try
    #! /usr/local/bin/perl

    $v1 = "foo";
    $v2 = "bar";
    $v3 = "baz";

    foreach my $arg (qw/ v1 v2 v3 /) {
    my $val = defined $$arg ? $$arg : "<undef>";
    print "name: \$$arg, value: $val\n";
    }

    % ./try
    name: $v1, value: foo
    name: $v2, value: bar
    name: $v3, value: baz

    You should feel dirty after such naughtiness. Go take a shower. :)

    Hope this helps,
    Greg
    --
    We believe--or we act as if we believed--that although an individual father
    cannot alienate the labor of his son, the aggregate body of fathers may
    alienate the labor of all their sons . . .
    -- Thomas Jefferson
     
    Greg Bacon, Jul 8, 2003
    #2
    1. Advertising

  3. Greg Bacon wrote:
    > In article <>,
    > Eric Pement <> wrote:
    >
    > : $v1 = "foo";
    > : $v2 = "bar";
    > : $v3 = "baz";
    > : foreach my $arg ($v1, $v2, $v3) {
    > : print "name: \\$arg, value: $arg\n";
    > : }
    > :
    > : Desired output:
    > :
    > : name: $v1, value: foo
    > : name: $v2, value: bar
    > : name: $v3, value: baz


    <snip>

    > foreach my $arg (qw/ v1 v2 v3 /) {
    > my $val = defined $$arg ? $$arg : "<undef>";
    > print "name: \$$arg, value: $val\n";
    > }


    Or without symrefs:

    foreach my $arg (qw/$v1 $v2 $v3/) {
    print "name: $arg, value: ", eval $arg, "\n";
    }

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 8, 2003
    #3
  4. On 7/8/2003 12:51 PM, Eric Pement wrote:
    >
    > I'd like to do is something like this, where foreach() is
    > followed by a list of scalars:
    >
    > $v1 = "foo";
    > $v2 = "bar";
    > $v3 = "baz";
    > foreach my $arg ($v1, $v2, $v3) {
    > print "name: \\$arg, value: $arg\n";
    > }
    >
    > Desired output:
    >
    > name: $v1, value: foo
    > name: $v2, value: bar
    > name: $v3, value: baz
    >
    > How do I retrieve the name of the variable instead of its value?


    Are the variables globals or lexicals? If they're lexicals, you
    (typically) don't. The variable names aren't stored anyplace normally
    accessible. That said, the PadWalker module may do what you want. I've
    never used it, so I can't give you any pointers there. Check the docs
    and search the newsgroup archives for examples.

    If the variables are globals, you could walk the symbol table. Quick &
    dirty example:

    #!/rfs/apps/bin/perl5.6.1 -w
    use strict;
    use warnings;

    our $v1 = 'foo';
    our $v2 = 'bar';
    our $v3 = 'baz';

    foreach my $arg ($v1, $v2, $v3) {
    for my $vn (keys %main::) {
    no strict 'refs';
    if (*{"*main::$vn"}{SCALAR} eq \$arg) {
    print "name: \$$vn, value = '$arg'\n";
    }
    }
    }
    __END__
    name: $v1, value = 'foo'
    name: $v2, value = 'bar'
    name: $v3, value = 'baz'

    -mjc
     
    Michael Carman, Jul 8, 2003
    #4
  5. Also sprach Gunnar Hjalmarsson:

    > Greg Bacon wrote:
    >> In article <>,
    >> Eric Pement <> wrote:
    >>
    >> : $v1 = "foo";
    >> : $v2 = "bar";
    >> : $v3 = "baz";
    >> : foreach my $arg ($v1, $v2, $v3) {
    >> : print "name: \\$arg, value: $arg\n";
    >> : }
    >> :
    >> : Desired output:
    >> :
    >> : name: $v1, value: foo
    >> : name: $v2, value: bar
    >> : name: $v3, value: baz

    >
    ><snip>
    >
    >> foreach my $arg (qw/ v1 v2 v3 /) {
    >> my $val = defined $$arg ? $$arg : "<undef>";
    >> print "name: \$$arg, value: $val\n";
    >> }

    >
    > Or without symrefs:
    >
    > foreach my $arg (qw/$v1 $v2 $v3/) {
    > print "name: $arg, value: ", eval $arg, "\n";
    > }


    Or with strict-proof symrefs:

    use strict;

    # those need to be package-qualified (or our()ed or 'use var'ed)
    $::v1 = "foo";
    $::v2 = "bar";
    $::v3 = "baz";

    foreach my $arg (qw/v1 v2 v3/) {
    print "name: \$$arg, value: ${ $::{ $arg } }\n";
    }

    Not that strictures would matter here a lot, though.

    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, Jul 8, 2003
    #5
  6. Tassilo v. Parseval wrote:
    > Also sprach Gunnar Hjalmarsson:
    >
    >>Or without symrefs:
    >>
    >> foreach my $arg (qw/$v1 $v2 $v3/) {
    >> print "name: $arg, value: ", eval $arg, "\n";
    >> }

    >
    > Or with strict-proof symrefs:
    >
    > use strict;
    >
    > # those need to be package-qualified (or our()ed or 'use var'ed)
    > $::v1 = "foo";
    > $::v2 = "bar";
    > $::v3 = "baz";
    >
    > foreach my $arg (qw/v1 v2 v3/) {
    > print "name: \$$arg, value: ${ $::{ $arg } }\n";
    > }
    >
    > Not that strictures would matter here a lot, though.


    But if the variables OP is exploring include lexically scoped
    variables, symrefs isn't such a good idea, right?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jul 8, 2003
    #6
  7. Eric Pement

    Eric Pement Guest

    Gunnar Hjalmarsson <> wrote in message news:<bef2rm$4f99c$>...

    > foreach my $arg (qw/$v1 $v2 $v3/) {
    > print "name: $arg, value: ", eval $arg, "\n";
    > }


    This was exactly what I was looking for. Thanks!!

    --
    Eric Pement
     
    Eric Pement, Jul 8, 2003
    #7
    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. Clint Olsen
    Replies:
    6
    Views:
    377
    Jeff 'japhy' Pinyan
    Nov 13, 2003
  2. Mark

    Replace scalar in another scalar

    Mark, Jan 27, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    171
    Arndt Jonasson
    Jan 27, 2005
  3. Replies:
    8
    Views:
    91
  4. Replies:
    6
    Views:
    189
  5. Isaac Won
    Replies:
    9
    Views:
    397
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page