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

hello all,

i'm writing a bit of experimental code and i've run into 
an interesting wall.  how does one retrieve the characters
IN the scalar, array, or hash name?  ie:  how do i get 
the "example" in $example ( or @example / %example )?

i've been reading through programming perl ( 2nd + 3rd  editions ).  
i can automagically generate hashes on the 
fly using symbolic references, but cannot seem to pull 
the text of the name back out.

i suspect that i can do it through the symbol table, but 
i don't understand all of that aspect of perl yet.

also, this is not about solving a programming problem...
it's something that i became interested in while researching
something else.  ( i got around it by keeping a list of
what was automagically built.  :)

thanks,

moo

Replies are listed 'Best First'.
Re: getting at the text of an icon
by wog (Curate) on Dec 13, 2001 at 08:16 UTC

    Short answer: you can't do that; you shouldn't be doing that.

    Long answer: you can do it, sometimes; but it's not really a good idea.

    For variables in the symbol table, you can find this information, by recursing through the symbol table, with something like this (this example only works on scalars, extending it should be relatively simple, see also perlref):

    # This code is not tested. Sorry. sub _find_var_loop { my($hash,$prefix,$var) = @_; my @results; # go through each entry in our symbol table hash... while (my($name,$glob) = each %$hash ) { if ($var eq \${ $glob }) { push @results, $perfix.$var; # add $var to our list } # is it another symbol table hash? # (ignore main:: to not infinite loop) if ($name =~ /::\z/ and $name ne 'main::') { # recurse... push @results, _find_var_loop(\%{ $glob }, $prefix.$name, $var); } } return @results; } sub find_var { # usage: my @names = find_var($var); return _find_var_loop(\%main::, "", \$_[0]) }

    This function will find all variables with a certain values in the symbol table, by comparing the "SCALAR(0xDEADBEEF)"-like strings you get when you stringify references. (See also perlref). Note that I say all; there can be multiple copies of a variable in the symbol table when Exporter or the *glob = \$variable or *glob1 = *glob2 syntaxes are used. (This function returns the variable names from the prespective of the main package, since that's where it starts searching from, and I didn't want to have all the results have :: or main:: on the front.)

    However, this all won't work for my'd variables, which are generally preferred in perl code. You could probably do my'd variables with some C code, but I wouldn't count on it not breaking in future versions of perl. (There is nothing in the public API to do that.)

    Using variables as variable names is, in general, a very bad idea. See this set of articles. So, please, don't do that. You can, with a few rare exceptions, always use (possibly nested) data structures instead of variables as variable names.

    update: I realize (impossiblerobot's very closely spaced post reminded me) I didn't emphasize enough that this is going to inefficient. Searching through the symbol table is that way, and that's another reason why it's best left avoided.

      I agree this is really something not to do in real world programming, but I found it pretty interesting to write some JAPH/Obfu/Poetry. For example:
      package Love; $asami = 'Love'; print "I $asami " . (keys%Love::)[0];
      Anyway moo stated this is not about solving a programming problem so i suppose he is not going to use it in "real" programs.

      gkinueliileunikg

Re: getting at the text of an icon
by impossiblerobot (Deacon) on Dec 13, 2001 at 08:16 UTC
    Getting what's in the symbol table for a specific package is pretty easy:
    #!/usr/bin/perl package symTest; my $variable_zero = 0; $variable_one = 1; $variable_two = "blue"; $variable_three = 3; for (sort keys %symTest::) { print $_, "\n"; }
    However, you'll notice that $variable_zero doesn't show up in the list. That's because 'my'ed variables don't actually appear in the symbol table, so only global (and 'local') variables are listed. My guess is that it would be virtually impossible to get at the 'my' (lexical) variables (but we've got some pretty smart monks here). :-)
    Also note that I put the variables in a new package(symTest); the default "main" package has a lot of stuff in it's symbol table that you probably don't want to wade through.

    Impossible Robot
      Check out my PadWalker module for a way to get at lexical variables. Of course, that's an even worse idea unless you're doing some very deep magic. Or just for fun :-)
(shockme) Re: getting at the text of an icon
by shockme (Chaplain) on Dec 13, 2001 at 07:55 UTC
    If I understand what you're asking, you're wanting to do a symbolic reference. See this thread for why this is a bad idea.

    Update: See wog's post below for more complete information. It's far more complete.

    Again, this isn't a good idea.

    If things get any worse, I'll have to ask you to stop helping me.