|Keep It Simple, Stupid|
(tye)Re: Private Class Methodsby tye (Sage)
|on Apr 05, 2002 at 22:32 UTC||Need Help??|
I've starting writing more OO code more like:
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:
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).
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
would work. - tye (but my friends call me "Tye")