Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

symbolic references

by 7stud (Deacon)
on Jan 01, 2011 at 07:09 UTC ( #879970=perlquestion: print w/ replies, xml ) Need Help??
7stud has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I want to know why the symbolic reference in the following code does not generate an error when using strict:

use strict; use warnings; use 5.010; sub greet { say 'hello'; } sub test { goto &{"greet"}; #SYMBOLIC REFERENCE } test(); --output:-- hello

In the following line of code, "greet" is a string:

goto &{"greet"};

and it looks like the string is being dereferenced into a sub--yet strict 'refs' is in effect.

The above is a simplified version of the following code:

{package Dog; sub new { my $class = shift; bless {Name=>'Spot', Color=>"black"}, $class; } #For auto generating the getters: sub AUTOLOAD { my $self = shift; our $AUTOLOAD; my %methods = ( color => undef, name => undef, ); if ($AUTOLOAD =~ /::(\w+)\z/ and exists $methods{$1} ) { my $data_name = ucfirst $1; { no strict 'refs'; *{$AUTOLOAD} = sub { $self->{$data_name} }; } goto &{$AUTOLOAD}; } else { use Carp; croak "No method named $AUTOLOAD"; } } } my $dog = Dog->new; say $dog->name; say $dog->color;

Comment on symbolic references
Select or Download Code
Re: symbolic references
by Anonymous Monk on Jan 01, 2011 at 07:27 UTC
    Because that isn't a symbolic reference, it doesn't use any symbols

      According to "Programming Perl 3rd", p 263:

      What happens if you try to dereference a value that is not a hard reference? The value is then treated as a symbolic reference.

      In the line:

      goto &{"greet"};

      "greet" is not a hard reference, so what happens when you try to dereference a value that is not a hard reference, e.g. {"greet"}? According to "Programming Perl", the string is treated as a symbolic reference. As far as I can tell, dereferencing the string "greet" is the very definition of a symbolic reference.

      It's my understanding that my code tells perl to look in the symbol table for the name "greet" and return the appropriate part of greet's typeglob: the coderef part. On the other hand, a hard reference points directly at the data in memory so a hard reference doesn't need to access the symbol table to find the data.

        Hahaha, well, greet is a string constant. Its is not a variable; and strict says
        "strict refs" This generates a runtime error if you use symbolic references (see perlref). use strict 'refs'; $ref = \$foo; print $$ref; # ok $ref = "foo"; print $$ref; # runtime error; normally ok $file = "STDOUT"; print $file "Hi!"; # error; note: no comma after $file There is one exception to this rule: $bar = \&{'foo'}; &$bar; is allowed so that "goto &$AUTOLOAD" would not break under stricture.

      It sure is a symbolic reference.

      >perl -e"use strict 'refs'; ${'foo'} = 1;" Can't use string ("foo") as a SCALAR ref while "strict refs" in use at + -e line 1. >perl -e"use strict 'refs'; &{'foo'}" Can't use string ("foo") as a subroutine ref while "strict refs" in us +e at -e line 1. >perl -e"use strict 'refs'; goto &{'foo'}" Goto undefined subroutine &main::foo at -e line 1.

      You can dereference references and strings. We call the latter "symbolic references" because the reference is a symbol name rather than a true reference. It doesn't matter whether the string is returned from a variable, a string literal or some more complex expression.

Re: symbolic references
by james2vegas (Chaplain) on Jan 01, 2011 at 09:08 UTC
    This is a deliberate exception, see strict:

    There is one exception to this rule: $bar = \&{'foo'}; &$bar; is allowed so that "goto &$AUTOLOAD" would not break unde +r stricture.
    and running your code through B::Deparse you get (leaving out all the 'feature' stuff):
    sub test { goto \&{'greet';}; }
    which triggers the exception.

    UPDATE: checking your actual code, it is in sub AUTOLOAD, exactly the reason why the exception exists. If something about strict mode confuses, check strict first.
Re: symbolic references
by 7stud (Deacon) on Jan 01, 2011 at 09:32 UTC

    Hahaha, well, greet is a string constant. Its is not a variable

    Why is that significant? Is the following code different somehow?

    use strict; use warnings; use 5.010; sub greet { say 'hello'; } sub test { my $str = "greet"; goto &{$str}; #SYMBOLIC REFERENCE } test();

    I'm still dereferencing something that is not a hard reference, {$str}, ergo according to "Programming Perl" the "value" is a symbolic reference. And it's my understanding that the only way perl can find the greet() subroutine is by looking in the symbol table--because the string 'greet' does not point to a subroutine somewhere in memory.

      Is the following code different somehow?

      Yes. Perl 5 doesn't perform dataflow analysis to prove that $str can't possible change between assignment and the symbolic reference.

      I can think of a way to make test call a function besides greet without personally writing any XS.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://879970]
Approved by GrandFather
Front-paged by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2014-09-17 10:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (72 votes), past polls