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

Given this script:
my $string = 'foo'; my $variablename = 'string'; my $temp = ${$variablename}; print $temp, $/;
What would you expect it to print?

It prints only $/, because $temp gets nothing from the assignment.

However this:

$string = 'foo'; my $variablename = 'string'; my $temp = ${$variablename}; print $temp, $/;
works as expected.

I can't run the first one under strict, because it won't allow the scalar reference.

But when I run it with warnings, the only warning I get is about the uninitialised value in the concatenation.

What am I missing about scope here?

P.S. I really do know why coding this way is a Bad Idea. I was in a big hurry!



($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
=~y~b-v~a-z~s; print

Replies are listed 'Best First'.
Re: Scope Puzzle
by merlyn (Sage) on Feb 17, 2006 at 01:27 UTC
Re: Scope Puzzle
by GrandFather (Saint) on Feb 17, 2006 at 01:44 UTC

    My understanding was helped by this variant (note the 'our'):

    our $string = 'foo'; my $variablename = 'string'; my $temp = ${$variablename}; print $temp, $/;

    Prints:

    foo

    DWIM is Perl's answer to Gödel
Re: Scope Puzzle
by ikegami (Patriarch) on Feb 17, 2006 at 05:41 UTC

    There are two kinds of variables in Perl: lexical (my) variables and package (our) variables. If you don't declare a variable, Perl assumes it's a package variable.

    Symbolic references (e.g. ${'varname'}) can only fetch and set the value of package variables.

    Symbolic references are strongly discouraged. In fact, they won't even work if you use use strict as you should. Hashes or arrays usually do the trick. If you're looking to create aliases, check out Data::Alias.

    (I wrote this earlier, but forgot to post it.)

Re: Scope Puzzle
by chromatic (Archbishop) on Feb 17, 2006 at 06:36 UTC

    As an optimization (I suspect) of an implementation detail, perl translates lexical variables into array accesses, where each lexical pad is an array. That's not quite exactly correct, but it's close enough to explain why you can look up and rebind global symbols -- those that live in the symbol table -- but not lexicals. perl always looks up global symbols (package variables, subroutine names) by name and lexical symbols by lexical pad index.

    If you examine the optree with B::Concise or a similar module, you'll notice the difference in gvsv and padsv ops.

      No, its because it was designed that way %)