Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re^2: OO - best way to have protected methods

by jdporter (Paladin)
on Aug 17, 2005 at 19:37 UTC ( [id://484556]=note: print w/replies, xml ) Need Help??


in reply to Re: OO - best way to have protected methods
in thread OO - best way to have protected methods

As currently implemented, that only works in the first module that calls is_private. Witness:
package Foo; use Private; sub foo { is_private; } package Bar; use Private; sub bar { is_private; } package main; Bar->bar;
main cannot call Bar::bar (private to Foo)

Replies are listed 'Best First'.
Re^3: OO - best way to have protected methods
by radiantmatrix (Parson) on Aug 18, 2005 at 15:14 UTC

    Yeah, that module took me all of five minutes. It works if you use or require several different modules, but not if you create several in the same file. I don't know why this is, and therefore I don't know how to fix it. Patches and/or explanations would be welcome.

    And, BTW, it's not the first package to call is_private, but rather the first to use Private -- the init is done (and the 'private' package name determined) during import.

    I don't really have the drive to create something to solve this problem, as I don't really consider it a problem: I use the suggested syntax for methods/subs/variables I wish to be private (prepend the name with an underscore), and document that these are not intended for consumption outside the module code.

    If people want to shoot themselves in the foot by using subs/etc. I've marked as "I want this to be private", then I have no problem letting them. ;-)

    <-radiant.matrix->
    Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
      The problem, of course, is in the
      my $PACKAGE = caller(0);
      happening at package level.

      Below is an implementation of your approach which is entirely scalable. It doesn't "remember" anything from 'import' time; it simply compares the package of the caller to the package of the callee, and requires that they be the same.

      package Private; use Exporter; @ISA = 'Exporter'; @EXPORT = 'is_private'; use strict; use warnings; use Carp; sub is_private() { my %c0; @c0{qw( pkg fn l sub )} = caller 0; my %c1; @c1{qw( pkg fn l sub )} = caller 1; if ( $c0{'pkg'} ne $c1{'pkg'} ) # throw an exception: { my %c2; @c2{qw( pkg fn l sub )} = caller 2; my $caller = $c2{'sub'} || $c2{'pkg'} || 'main'; croak "$caller cannot call $c1{'sub'} (private to $c0{'pkg'})" +; } } 1;
      Here's a little test rig.
      { package Parent; use Private; sub private_method { is_private; print "Private method calleed OK.\n +" } sub public_method { $_[0]->private_method } } { package Child; use base 'Parent'; sub child_calling_private { $_[0]->private_method } sub child_calling_public { $_[0]->public_method } } package main; print "\nBase class: call private method directly:\n"; eval { Parent->private_method }; $@ and print $@; print "\nBase class: call public method that calls private method:\n"; eval { Parent->public_method; }; $@ and print $@; print "\nDerived class: call parent's private method directly:\n"; eval { Child->private_method }; $@ and print $@; print "\nDerived class: call parent's public method that calls private + method:\n"; eval { Child->public_method; }; $@ and print $@; print "\nDerived class: call method that calls parent's private method +:\n"; eval { Child->child_calling_private; }; $@ and print $@; print "\nDerived class: call method that calls parent's public method: +\n"; eval { Child->child_calling_public; }; $@ and print $@;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://484556]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (9)
As of 2024-03-28 12:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found