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

I would appreciate it if anyone could give me an idiots guide to symbolic references. I understand Hard ref's but symbolic ones just wont fit in my little brain. Ive read explanations in the best known Perl books and all the doc's available on the subject but none are simple enough for me. If possible could you include information on dereferencing (and maybe how the symbol table fits into the equation). I know its a hell of alot to ask, but until i thoroughly understand this i cant fully understand the debugging concept of "use strict 'refs'". I hope this is not an unworthy question, but I realy am a "first principles" kinda person, who needs a good conceptual grasp of something to understand it. TIA

Replies are listed 'Best First'.
Re: Symbolic References
by Joost (Canon) on Nov 26, 2006 at 20:21 UTC
    Simply put, symbolic refs are strings that contain the name of a (package global) variable, that you can use as a reference. Using use strict 'refs'; disables this (often too powerful and bug-prone) feature.

    For example:

    no strict 'refs'; $bla = "something"; $blaref = "bla"; $$blaref = "something else"; print $bla; # prints "something else"
    Note that if you get the value of $blaref wrong, you'll just reference (and probably create) another variable without any warning whatsoever.

    Just about the only reason to use symbolic reference nowadays is to dynamically create named subroutines or classes (i.e. setting @{"${classname}::ISA"})

    my $subname = "packagename::some_sub"; no strict 'refs'; # note that we use a typeglob here *$subname = sub { print "Hello from subroutine $subname"; }; packagename::some_sub();
    See also perldata on typeglobs. and perlmod on Symbol tables
Re: Symbolic References
by grep (Monsignor) on Nov 26, 2006 at 19:35 UTC
    Simply, a symbolic reference generally uses the value of a variable1 as another variable's name.
    # A simple example from http://perldoc.perl.org $name = "foo"; $$name = 1; # Sets $foo # $name is evaluated ("foo") as the name of the variable

    Which is almost always NOT what you want to do (unless you really understand symbolic refs and have a good reason to do so). So if your code doesn't run under use strict 'refs'; you are accidentally using symbolic refs. This is why, using strict is often harped on.

    While you are learning perl, it is much better to know how to avoid symbolic refs than knowing the details of them.

    This is most likely your best reference.

    UPDATE: 1 It can actually be any value, or expression that evaluates to a string. Thanks jdporter

    grep
    XP matters not. Look at me. Judge me by my XP, do you?
      so are you saying that "foo", once a text string stored in $name, is now a variable in its own right with the value 1 stored in it? I think im still confused (oh and by the way, I read perlref and didnt get that either)
Re: Symbolic References
by eyepopslikeamosquito (Archbishop) on Nov 26, 2006 at 20:29 UTC

    Symbolic references should be avoided as much as possible, as convincingly demonstrated by MJD in three parts: part 1 and part 2 and part 3.

    If you have a specific problem where you feel you need to use symbolic references, post your problem and we can advise on a cleaner way to solve it.

Re: Symbolic References
by jbert (Priest) on Nov 27, 2006 at 09:47 UTC
    Symbolic references are a lot like hash keys (really like them if you dig down far enough). So if you have:
    use warnings; use strict; no strict 'refs'; my %hash = ( badger => 'nadger', mutt => 'nut' ); # Package variable, named badger our $badger = 'furry'; # Lexical variable - gives a warning that it is shadowing # the package var my $badger = 'stripey'; my $str = 'badger'; # The value of $str is used to lookup in the hash # Hence this prints 'nadger' print $hash{$str}, "\n"; # With strict refs off, we can use '$str' as a reference and # so this prints 'furry', the value of the $badger package var print ${$str}, "\n"; # This is a normal variable lookup, whose value will be # 'stripey', since the lexical is shadowing the package var # in this scope. print $badger, "\n";
    then you can see that using a symbolic reference is a bit like looking something up in an un-named hash. In fact, this is almost exactly what is going on, since the package variables are stored in a hash associated with the package. (The only difference is that there is an extra layer of indirection, to sort out the difference between things with different types but the same name: $badger, @badger, %badger etc.)

    This means that symbolic references have similar properties to hash keys, in particular perl can't check at compile time whether you have mis-spelled the variable name, instead it will just look up the wrong name give you an undef value.

    Also as you can see, symbolic references don't really have much advantage over hashes, if you think you want a symbolic reference, it is quite likely a hash will do the job for you.

    And lastly, emulating a structure by using named keys in a hash shares some of the disadvantages of symbolic references. If you're using a hash reference to implement an object you can get compile-time checking back again by using accessors, made easy by handy modules such as Class::Accessor.

Re: Symbolic References
by gam3 (Curate) on Dec 01, 2006 at 12:30 UTC
    In perl 4, before there where references, symbolic refereces where needed to make multi-dimintional arrays and hashes.

    Now that perl has references there are very few reasons to use these.

    our $reference = "global"; { my $reference = "local"; print "reference equals ${reference}, "; print "symbolic reference equals ${'reference'}.\n"; } print "Here ${reference} and ${'reference'} both come out of the sysbo +l table.\n"; print "This also shows how local differs from local\n"; { local $reference = "local"; print "reference equals ${reference}, "; print "symbolic reference equals ${'reference'}.\n"; }
    I don't know if this makes symbolic references clearer for you, but it did for me. Thanks for the question.
    -- gam3
    A picture is worth a thousand words, but takes 200K.