Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

(tye)Re: Private Class Methods

by tye (Sage)
on Apr 05, 2002 at 22:32 UTC ( [id://157074]=note: print w/replies, xml ) Need Help??


in reply to Private Class Methods

I've starting writing more OO code more like:

package My::Class; use vars qw( $VERSION ); BEGIN { $VERSION= 1.001 } package My::Class::_internal; sub My::Class::new { my $self= bless {}, "My::Class::_object"; #... return $self; } sub utilityFunction { my $self= shift @_; # ... } sub My::Class::_object::method { my $self= shift @_; # ... utilityFunction( $self, @args ); # ... }
That is, have only class methods in the My::Class namespace, have only object methods in the My::Class::_object namespace, and put utility function in some other namespace (package). Note that all of the functions are actually compiled in the "internal" package (even though they are named into a different package) so that they can call utility function w/o specifying a package name.

This prevents the module user from making the following mistakes:

# Calling a class method via an object: my $obj2= $obj1->new(); # Calling an object method via the class name: my $ret= My::Class->method() # Using my utility function: $obj->utilityFunction();
Note that this prevents naive inheritance from working. I don't mind much as I think that inheritance should be mostly a last-resort technique and should not be used with a class that wasn't specifically designed to allow inheritance. You can also think of My::Class as a "factory" class, if that makes you feel better (in fact, several of my recent classes really were factory classes).

Of course, you might well want to follow OO Perl tradition (what little there is of it, OO Perl being so young) and allow $obj->new(). One way to do that is by "exporting" sub new:     *My::Class::_object::new= \&My::Class::new; or you can just not separate your object methods from your class methods, instead just separating your utility functions (note that the utility functions are not methods because calling them as methods just adds overhead in order to search the inheritance heirarchy but you don't want to allow them to be overridden via inheritance so that would just be a waste).

The following example does that and even uses Exporter.pm. You can also use Exporter.pm when you separate everything (like the first example does), and it can be quite nice, especially if you have lots of methods. It is even nicer if you have multiple object types and some methods are shared among multiple object types (yes, you can share methods with less flexibility via inheritance).

package My::Class; use vars qw( $VERSION ); BEGIN { $VERSION= 1.001 } # Following line moved down to increase robustness: ## My::Class::_internal->import( ":DEFAULT" ); package My::Class::_internal; require Exporter; use vars qw( @EXPORT_OK ); BEGIN { *import= \&Exporter::import; @EXPORT_OK= qw( new method ); } sub utilityFunction { my $self= shift @_; # ... } sub new { my $class= shift @_; my $proto; $class= ref( $proto= $class ) if ref $class; my $self= bless {}, $class; #... return $self; } sub method { my $self= shift @_; # ... utilityFunction( $self, @args ); # ... } package My::Class; My::Class::_internal->import( ":DEFAULT" );
Note that there are lots of ways you can deal with getting things to happen in the proper order here. The above commented line would work because it is not in a BEGIN block while "everything" else is. But I show the last two lines instead as they are less sensitive to having something in a BEGIN block that shouldn't be or vice versa.

You can even create a separate My/Class/_internal.pm file so that a standard

package My::Class; use My::Class::_internal;
would work.

        - tye (but my friends call me "Tye")

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-12-07 06:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Which IDE have you been most impressed by?













    Results (49 votes). Check out past polls.