Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
The stupid question is the question not asked
 
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-04-20 04:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls