Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

OOP: Obj->Coderef for calling Private Methods

by LanX (Chancellor)
on Dec 13, 2008 at 17:00 UTC ( #730166=perlquestion: print w/replies, xml ) Need Help??
LanX has asked for the wisdom of the Perl Monks concerning the following question:


continuing this discussion in German.

please look at this suggestion of "Programming Perl, 3rd Edition, Chapter 12.5" how to realize a private method:

# An intriguing aspect of this behavior is that it can be # used to implement private method calls. If you put your # class in a module, you can make use of the file's lexical # scope for privacy. First, store an anonymous subroutine # in a file-scoped lexical: # declare private method my $secret_door = sub { my $self = shift; ... }; # Later on in the file, you can use that variable as though # it held a method name. The closure will be called directly, # without regard to inheritance. As with any other method, # the invocant is passed as an extra argument. sub knock { my $self = shift; if ($self->{knocked}++ > 5) { $self->$secret_door(); # *** } }

this stupified me... at *** , the RHS of -> is a coderef

OK, looking at perlop reveals

Otherwise, the right side is a method name or a simple scalar variable
containing either the method name or a subroutine reference, and the 
left side must be either an object (a blessed reference) or a class name 
(that is, a package name). See perlobj.

but seeking thru perlobj doesn't give me any more infos!

does anybody have a link to a perldoc with a complete definition of this magic behaviour?

Or: What should exactly happen when the RHS of -> is a coderef???

In this example, what is the difference to &$secret_door() except that $self is passed as first parameter? Is there any other difference?

I'm sure this has been discussed before but supersearch didn't help me find any clue...

Cheers Rolf

Replies are listed 'Best First'.
Re: OOP: ->Coderef for calling Private Methods
by ccn (Vicar) on Dec 13, 2008 at 17:43 UTC
    > what is the difference to &$secret_door() except that $self is passed as first parameter?

    I do not see any reason for the difference. And the docs are clear and complete here as it seems to me.
    $obj->$coderef() must behave the same way as $obj->methodname().

      > I do not see any reason for the difference.

      I agree there is no logical reason for extra behaviour...

      > And the docs are clear and complete here as it seems to me.

      Sorry, I disagree! Till now, I couldn't find any other perldoc describing this feature , and perlop is just a condensed quick reference. IMHO Perl has to many special cases to rely on just 3 words in a quickref.

      I think it's quite unknown, taking into consideration that most hacker prefere the _underscore_private_method() convention instead.

      Even Merlyn's Book on Perl-Objects and Refrences doesn't list this behaviour, (at least it's not indexed)

      For me it looks like the documentation should be improved!

      Cheers Rolf

      UPDATE: And what really makes my brain stumble, what is the expected behaviour when i call $obj->$code_ref() and code_ref doesn't point to a method (of the blessed package).

      Am I supposed to run experiments to find it out?

      Please can anyone give me a link to any documentation!

        What are the possibilities that you can't decide between without experiments? $obj->$code_ref(...) is the same as $code_ref->( $obj, ... ) and that seems pretty clear from the documentation.

        That the method is specified from a code ref would only change the fact that there is no need to look anything up in @ISA.

        code_ref doesn't point to a method

        Perl 5 has no concept of "method" separate from "sub" so it isn't possible for a code ref to point to something that isn't just the same as a method.

        Clearly you can use this technique to dispatch to something that can't be used as a regular method of a class since otherwise there would be little point in using the word "private" in the description.

        - tye        

        Perl 5.6 does not have that feature (perlop 5.6). That explains why hackers use underscores and merlyn did not mention it in his book.

        Perl doesn't care about $code_ref having to be a reference to a method. It's enough to be just a sub ref. The sub gets an $obj as first argument, that's all.

        Update: broken link fixed

Re: OOP: Obj->Coderef for calling Private Methods
by ig (Vicar) on Dec 15, 2008 at 02:56 UTC

    Would the following addition to perlobj, at the end of the Method Invocation section be reasonably correct and clear?

    If the right side of the arrow is a scalar containing a reference to a subroutine then this is equivalent to calling the referenced subroutine directly with the class name or object on the left side of the arrow as its first argument. No lookup is done and there is no requirement that the subroutine be defined in any package related to the class name or object on the left side of the arrow. For example, the following calls to $display are equivalent: my $display = sub { my $self = shift; ... }; $fred->$display("Height", "Weight"); $display->($fred, "Height", "Weight");

    If so, I would submit a patch to the documentation.

    Update: PerlBug 61392


      Cheers Rolf

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://730166]
Approved by holli
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2017-03-30 11:21 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (356 votes). Check out past polls.