Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

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 You can also use 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/ file so that a standard

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

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

In reply to (tye)Re: Private Class Methods by tye
in thread Private Class Methods by dhable

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2023-03-27 16:52 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (65 votes). Check out past polls.