Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Variable name

by nsteiner (Novice)
on Dec 08, 2008 at 14:45 UTC ( [id://728964]=perlquestion: print w/replies, xml ) Need Help??

nsteiner has asked for the wisdom of the Perl Monks concerning the following question:

Hi all
I am trying to concatenate a string and a value of a
variable to construct the name of a known variable.
For example:
$foo="foo";
$bar="f";
print ${$bar.'oo'} should give out: "foo" but it doesn't.
Now, before you say anything, yes, I know, I should use a hash instead, but humor me, would you ?

Thanks
Noam

Replies are listed 'Best First'.
Re: Variable name
by almut (Canon) on Dec 08, 2008 at 15:08 UTC

    Are you, by any chance, using a lexical ('my') variable for $fooSymbolic references only work with package variables:

    #!/usr/bin/perl use strict; use warnings; our $foo="foo"; my $bar="f"; no strict 'refs'; print ${$bar.'oo'}, "\n";

    (BTW, just in case you're intending to create enumerated variables like $var1, $var2, etc., consider using an array instead...)

      It worked !
      Thanks a lot.
Re: Variable name
by BrowserUk (Patriarch) on Dec 08, 2008 at 15:00 UTC
    ... but it doesn't.

    What does it do? (This is nearly always a more useful metric :)

    I ask, because for me, (in the absence of strict), it works as expected whether I use globals or lexicals:

    $foo = 'foo';; $bar = 'f';; print ${ $bar . 'oo' };; foo { my $foo = 'foo'; my $bar = 'f'; print ${ $bar . 'oo' }; } foo

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      (in the absence of strict), it works as expected whether I use globals or lexicals

      Really?  It doesn't work for me with lexicals (neither with Perl 5.8.8, nor 5.10.0) — which confirms what the docs are saying:

      "Only package variables (globals, even if localized) are visible to symbolic references. Lexical variables (declared with my()) aren't in a symbol table, and thus are invisible to this mechanism."
        Really? It doesn't work for me with lexicals

        My bad!

        The output I showed was genuine, but all conducted in a single run of the debugger.

        Which explains it, (though it doesn't exactly satisfy the concept of least surprise), as the globals also existed despite that I had created similarly named lexicals. Which, (apparently naively), I expected to override the globals at the local scope.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Like I said:
      "Use of uninitialized value in print"
        Like I said: "Use of uninitialized value in print"

        Sorry, but where exactly did you say that?

        Hi all

        I am trying to concatenate a string and a value of a variable to construct the name of a known variable.

        For example:

        $foo="foo"; $bar="f"; print ${$bar.'oo'}

        should give out: "foo" but it doesn't.

        Now, before you say anything, yes, I know, I should use a hash instead, but humor me, would you ?

        Thanks

        Noam


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Variable name
by johngg (Canon) on Dec 08, 2008 at 15:16 UTC
    I should use a hash instead, but humor me, would you ?

    Well, just this once :-)

    Actually, it works for me on the command line if not using strictures and not declaring the variables so they default to being package variables.

    $ perl -le ' > $foo = q{foo}; > $bar = q{f}; > print ${$bar . q{oo}};' foo $

    Enabling strictures and using lexical varables throws a "strict refs" error

    $ perl -Mstrict -wle ' > my $foo = q{foo}; > my $bar = q{f}; > print ${$bar . q{oo}};' Can't use string ("foo") as a SCALAR ref while "strict refs" in use at + -e line 4. $

    Turning the stricture off inside the print statement throws an "uninitialsed value" warning because you can't have soft references with lexical variables.

    $ perl -Mstrict -wle ' > my $foo = q{foo}; > my $bar = q{f}; > print do {no strict q{refs}; ${$bar . q{oo}} };' Use of uninitialized value in print at -e line 4. $

    Declaring the variables as package variables with our gets things working again.

    $ perl -Mstrict -wle ' > our $foo = q{foo}; > our $bar = q{f}; > print do {no strict q{refs}; ${$bar . q{oo}} };' foo $

    But having said all of that, you really should be using a hash and should avoid soft references like the plague if at all possible.

    Cheers,

    JohnGG

Re: Variable name
by JadeNB (Chaplain) on Dec 08, 2008 at 22:37 UTC
    Everyone's been very helpful, so I think one of us is entitled to be cranky: Why are we humouring you (as opposed to linking to Why it's stupid to use a variable as a variable name)? That is, is this approach actually essential for some application, or were you puzzling out for “academic” interest why a construct wasn't working as expected (or is it some more sinister other, like that you're intending to use soft references after all?).
      In the OP's defense, there are still plenty of uses for symbolic references. Especially when you're building code that generates functions / classes / packages.

      Symbolic refs are notoriously easy to get wrong, but perl's code-generation constructs are only just about adequate, and it's usually a case of either using symbolic refs or eval STRING, and eval STRING is usually just too messy (and slow).

Re: Variable name
by MidLifeXis (Monsignor) on Dec 08, 2008 at 14:54 UTC
    $foo="foo"; $bar="f"; print ${$bar."oo"}, "\n";

    Not certain what your issue is. Perhaps the output is being overwritten by your prompt. Try ending the print with a newline.

    --MidLifeXis

      perl -v This is perl, v5.8.8 built for PA-RISC2.0

      What version of perl are you using?

      Also, is this part of a larger script (perhaps including use strict; use warnings;), or have you tried running this snippet as a standalone script?

      --MidLifeXis

      Nope, still doesn't work. I am getting a 'Use of uninitialized value in print' Maybe something else I am forgetting ?
Re: Variable name
by f00li5h (Chaplain) on Dec 08, 2008 at 23:07 UTC

    ... you really do want a hash.

    use warnings; use strict; my %f = ( oo => 'cats' ); print $f{ oo };

    using an explicit hash instead of using the symbol table as a hash seems like the right thing to do ...

    @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;

    Update would have worked just as well as a reply to Re^2: Variable name by Joost

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://728964]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-24 03:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found