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, Jul 8, 2003
    #1
    1. Advertisements

  2. Eric Pement

    Greg Bacon Guest

    : $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
     
    Greg Bacon, Jul 8, 2003
    #2
    1. Advertisements

  3. Or without symrefs:

    foreach my $arg (qw/$v1 $v2 $v3/) {
    print "name: $arg, value: ", eval $arg, "\n";
    }
     
    Gunnar Hjalmarsson, Jul 8, 2003
    #3
  4. 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:
    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
     
    Tassilo v. Parseval, Jul 8, 2003
    #5
  6. But if the variables OP is exploring include lexically scoped
    variables, symrefs isn't such a good idea, right?
     
    Gunnar Hjalmarsson, Jul 8, 2003
    #6
  7. Eric Pement

    Eric Pement Guest

    This was exactly what I was looking for. Thanks!!
     
    Eric Pement, Jul 8, 2003
    #7
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.