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

Is this a symbolic reference?

by demerphq (Chancellor)
on Jan 16, 2002 at 21:49 UTC ( #139254=perlmeditation: print w/replies, xml ) Need Help??

In a conversation today I was discussing using the following synatx
my $obj = Class->new(); my $method = "mymethod"; $obj->$method; #this is the question
Now this was at one point refered to as a symbolic reference. But for a variety of reasons I wouldnt call it a symbolic reference, but after some thought I havent the foggiest what it should be called. For the lack of a better name I picked method reference, but im not even sure that that is correct either.

So, what is the correct term?

Thanks all, I know this is a silly question but things like this bug me... :-)

Yves / DeMerphq
When to use Prototypes?

Replies are listed 'Best First'.
Re: Is this a symbolic reference?
by japhy (Canon) on Jan 16, 2002 at 22:15 UTC
    Well, it can't really be a symbolic reference because it is allowed while using strict. It's merely dynamic method invokation.

    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Dynamic Method Invocation.

      Cool. Thanks japhy. Now maybe i'll be able to sleep tonight.. :-)

      Although any other ideas are still welcome..

      Yves / DeMerphq
      When to use Prototypes?

Re: Is this a symbolic reference?
by redsquirrel (Hermit) on Jan 16, 2002 at 22:01 UTC
    Here is a related discussion from c.l.p.m.



    Here's another discussion from c.l.p.m that sheds a little more light on the question. Quoting TheDamien:

    In fact the $bar->$ref syntax is the preferred one - it makes it clearer you're doing a method call.

    Note that you can also use symbolic references and write...

    So I guess this confirms your decision not to call $obj->$method a symbolic reference.
      But unfortunately it doesnt answer the question...

      Man. Until someone gives me a good answer this is gunna really bug me.. Sigh.

      Update: Hmm. I'd like to say that your update cleared the water, but some of the later posts in that thread have pushed me the other way. Uri Guttman for instance says it is a symbolic reference, TheDamians position is slightly less clear but perhaps also goes that way.

      Good links. Thanks a lot.

      Yves / DeMerphq
      When to use Prototypes?

        I think Damian's position is clear and the opposite of redsquirrel's interpretation of it. In other words, yes, it is a symbolic reference. You are using the symbolic name of the method. It isn't outlawed by use strict, and it isn't a symbolic reference to a variable, and it isn't a "bad thing". But it is a symbolic reference. It has to look up the name of the subroutine to call in the symbol table.

        To quote more context:

        "David Christensen" <> writes:

        >> my $ref = \&Bar::FooOnYou; >> $var->$ref("Howdy\n"); >OK interesting symetry with Martien's approach: >I'm wondering if this is TIMTOWDI, or if there's a gotcha in >there...

        No gotchas. In fact the $bar->$ref syntax is the preferred one - it makes it clearer you're doing a method call.

        Note that you can also use symbolic references and write:

        my $ref = "Bar::FooOnYou"; $var->$ref("Howdy\n");

        But you didn't hear that from me ;-)


        So, as with all symbolic references, it isn't the syntax ($obj->$ref(@args) in this case) that makes it symbolic or not. It is whether $ref contains a real reference or simply a string to be looked up in a symbol table (or perhaps several symbol tables in this case since inheritance might be involved).

        The alternatives are mostly just uglier and even have some bad features (like preventing late binding) so I'd just use this type of symbolic reference, call it "dynamic method invocation", and be happy.

        Update: The only thing "bad" I see about this is that, in some cases, it may allow something to be used that shouldn't (the usual problem with symbolic references). So I encourage you to have, if appropriate, a list of allowed methods when using this. But that won't always be appropriate.

        And if it weren't for Perl's somewhat sloppy OO model, I'd be even less worried. Many Perl OO classes will have subroutines that aren't meant to be object methods but that are in a symbol table such that they could be used as object methods. And this usage wouldn't catch such "mistakes". But using UNIVERSAL::can() wouldn't either. [ Nor would the usual $obj->method(), for that matter, except that you aren't supposed to write such code unless you've been told that it is okay. (: ]

        Update2: Drat. I just realized that there is a dark side to this. You can use evil like $ref= "main::Unsubscribe" to execute stuff that you really shouldn't. UNIVERSAL::can() has the same "security problem". So I strongly urge you to ensure there are no colons nor apostrophes in any method name that you use in this way. ):

        I'm tempted to consider this as a bug that should be fixed, but that goes somewhat against the grain of Perl...

                - tye (but my friends call me "Tye")
Re: Is this a symbolic reference?
by clintp (Curate) on Jan 16, 2002 at 22:36 UTC
    Now to really get your shorts in a twist:

    goto &{"foo"}

    Clearly has the form of a symref, and should be caught by strict -- but it's not. This was reported by me and mjd to p5p a while ago and it's an intentional exception to stricture. References: my report, mjd's report of nearly the same thing, the eventual explanation. The short version is that strict refs only applies to $%@* things, not &.

      The short version is that strict refs only applies to $%@* things, not &.

      Your short version seems to be a little too short perhaps:

      #!/usr/bin/perl -w use strict; sub foo { print "foo: @_\n" } my $symbolic = 'foo'; # This symbolic method invocation works in 5.6.1 # (but not in 5.00503) main->$symbolic; # foo: main # 'goto &$symbolic' works (in subroutines) sub bar { goto &$symbolic; # works # goto &{'foo'}; # works } bar(1,2,3); # But these symref calls don't work: &$symbolic; # ack! &{$symbolic}; # ook! &{"foo"}; # eek!

      There clearly appears to be an exception for goto &{"symref"} in terms of symbolic-ref style *calls*.

      The report you gave was slightly different --- taking a reference to a symbolically dereferenced subroutine works:

      use strict; sub foo { print "foo: @_\n"; } my $bar = "foo"; &foo; # works # &{$bar}; # ack! symref as a call doesn't work my $sref = \&{$bar}; # works! $sref->(1,2,3); # foo: 1 2 3

      The symbolic-deref for the purpose of taking a ref does indeed appear to be an exception that applies to & but not $%@*:

      use strict; my $foo = "this is foo"; my $bar = "foo"; my $ref = \${$bar}; # ack!
Re: Is this a symbolic reference?
by bdimych (Monk) on Nov 09, 2007 at 12:57 UTC
    O'Reilly "Programming Perl" (with camel) => 12.3.1. Method Invocation Using the Arrow Operator:

    Sometimes you want to invoke a method without knowing its name ahead of time. You can use the arrow form of method invocation and replace the method name with a simple scalar variable:

    $method = "summon"; $mage = Wizard->$method("Gandalf"); # Invoke Wizard->summon $travel = $companion eq "Shadowfax" ? "ride" : "walk"; $mage->$travel("seven leagues"); # Invoke $mage->ride or $mage-> +walk
    Although you're using the name of the method to invoke it indirectly, this usage is not forbidden by use strict 'refs', since all method calls are in fact looked up symbolically at the time they're resolved.

    as a result the term may be "symbolic method invocation"

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://139254]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (8)
As of 2018-11-20 15:16 GMT
Find Nodes?
    Voting Booth?
    My code is most likely broken because:

    Results (225 votes). Check out past polls.