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

I've tried looking for documentation for * but to no avail.
I have some inherited code which has a way of storing variables between sub calls, it was written to replicate some main frame functionality.
It works but I have no understanding of whats happening here.(The code is cut down a lot but is the real lines except the package name, strict is not in use)
while((my $varname, my $globvalue)= each %thepackage::){ local *varAlias = $globvalue; my $reftype = ref $varAlias; #do lots of over stuf }
My question has three parts
1. what is *varAlias
2. Why when I made a little test of this could, I could get it to compile and run but no value was assigned to $reftype.
3. Would not compile with strict in use.

Im sure that, as usual, the Monks will be able to help.
Update in my test I printed the value of $globvalue so I know there was something in it.

Replies are listed 'Best First'.
Re: Declareing something with a *
by Abigail-II (Bishop) on May 18, 2004 at 09:19 UTC
    what is *varAlias
    A type glob.
    Why when I made a little test of this could, I could get it to compile and run but no value was assigned to $reftype.
    Do you have references in your package? It works for me:
    #!/usr/bin/perl use warnings; $main::foo = []; while ((my $varname, my $globvalue) = each %main::){ local *varAlias = $globvalue; my $reftype = ref $varAlias; print "$varname = $reftype\n" if $reftype; } __END__ Name "main::foo" used only once: possible typo at /tmp/try line 5. foo = ARRAY
    Note that looping over the entries in a stash will not find any lexical variables.
    Would not compile with strict in use.
    That's because you never introduced $varAlias. Either use:
    our $varAlias = $globvalue;
    or
    use vars qw /*varAlias/;

    Abigail

      Thanks just spoted myself that my first test didn't contain a referance. That makes sense now. As for the strict thing I think my predcessor, who used strict everwhere else didn't follow this particular procedure through to the end.
      Thanks for your help.
Re: Declareing something with a *
by periapt (Hermit) on May 18, 2004 at 12:22 UTC
    1. *varAlias is a typeglob which is sort of a window into the symbol table where all the uses of varAlias are kept. For example, *varAlias{SCALAR} points to the scalar value referenced by $varAlias while *varAlias{ARRAY} points to the array referenced by @varAlias. (It's a bit more complicated than that but I think this covers the main point.) Since $globvalue is a scalar, *varAlias refers to a scalar value.

    2. It depends on whether there was a reference in %thepackage:: . The code $reftype = ref $varAlias is checking whether the value in $varAlias is a reference to something. The function ref returns true (actually the data type the reference refers to) or false ("") if $varAlias is not a reference. Thus, if there is no value assigned to $reftype, then it is likely you did not have any references in the %thepackage:: symbol table.

    3. use strict requires variables to be predeclared before use (among other things) Declare $varAlias with my or our before use and it will compile.

    Try perldoc perldata for info on typeglobs and perldoc -f ref for info on the function ref.

    PJ
    We are drowning in information and starving for knowledge - Rutherford D. Rogers
    What good is knowledge if you have to pull teeth to get it - anonymous
      3. use strict requires variables to be predeclared before use (among other things) Declare $varAlias with my or our before use and it will compile.
      Yeah, it will compile if you declare $varAlias with my, but that's as useful as removing the entire while block. Then the program will compile as well. If you declare $varAlias with my, you get a lexical $varAlias, with no relationship with the glob *varAlias. You want a package variable $varAlias, not a lexical $varAlias.

      Abigail

        This being because globs operate on the symbol table and variables declared with my don't end up in the symbol table.

        Declaring variables in perl really does seem quite a mess, between use vars,my,our,local,strict on/off. Doesn't matter 99% of the time but every so often something doesn't work quite the way I expect and it annoys me.
        Yeah, I see what you mean. my doesn't make sense within the scope of the while loop. I was actually thinking about declaring $varAlias so that it would be in the same scope as *varAlias but I didn't make that clear. Keeping with the idea that variables should be declared in the smallest scope possible, our is the better bet. I'm not always clear on the use of my, our and local. Since we are trying to access a more global variable in this while loop, would local work as well? From the code, it seems that the actual value in $varAlias upon entry is not important. Of course, if that is true, then why would we care to preserve its value?


        PJ
        We are drowning in information and starving for knowledge - Rutherford D. Rogers
        What good is knowledge if you have to pull teeth to get it - anonymous
      Thank you and also to Abigail for all the help on this. I'm starting to get to grips now with some of the more powerful features of this great language. A language which a lot of my old college lecturers said was very dangerous and only gudgingly showed us for CGI scripting, then a very new field. I only wish I'd been using it full time since then, and I might be able to answer more then I ask.
      Thanks again