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

Re: is this a perversion of OO principles?

by khkramer (Scribe)
on Jan 07, 2002 at 03:22 UTC ( [id://136734]=note: print w/replies, xml ) Need Help??


in reply to is this a perversion of OO principles?

The way in which you're using the -> operator and AUTOLOAD() is perfectly valid. Your solution is a very clean and perl-ish way to build the API that you need.

The really nifty thing about the Perl OO framework is how open and flexible it is. As with most everything else Perl, you have a great deal of choice in how you select/combine the OO features of the language for your particular application/architecture.

As you say, the -> operator is syntactic sugar. But that's not because of how you're using it -- it's *always* syntactice sugar. Really, really useful syntactic sugar. You never have to use the -> operator: you can "drop down a level" and think about Perl objects more along the lines of the way you might think about C structs:

# common, clean, readable, OO-ish way $foo->bar ( 'bash' ); # less common, probably less readable, way Foo::bar ( $foo, 'bash' );

You can even intermix the two calling styles, if you really want to.

As for leaning on AUTOLOAD(), check out how Socket.pm uses it:

# from 5.6.1's Socket.pm on Linux 2.4 sub AUTOLOAD { my($constname); ($constname = $AUTOLOAD) =~ s/.*:://; my $val = constant($constname, @_ ? $_[0] : 0); if ($! != 0) { my ($pack,$file,$line) = caller; croak "Your vendor has not defined Socket macro $constname, us +ed"; } eval "sub $AUTOLOAD () { $val }"; goto &$AUTOLOAD; }

Heh. Most of the XS-dependent core modules do really hairy things with AUTOLOAD(). In comparison, your stuff is a paragon of the virtuous, straight and narrow.

If you want to make the separation between your various MessageLibrary objects clear, you have a few choices. You could add a settable "type" field that would differentiate them. But a more OO-ish way -- if your collections of error messages are pretty stable -- would be to code up the different Library types as classes themselves (MessageLibrary::Error, MessageLibrary::Debug, etc), all inheriting from the base MessageLibrary class. With a properly-written constructor, probably the only thing that would need to be overridden in each child would be the hash of messages. Here's how I tend to code such things (each package in a separate file, and with a framework for calling a class-specific _init() sub, which is often necessary).

package MessageLibrary; use ... my $hash = { ... }; sub new { my ( $class, %args ) = @_; my $self = {}; bless ( $self, $class ); $self->_init(); return $self; } sub _init { ... } sub AUTLOAD() { ... } 1; #----------------------------- package MessageLibrary::Error; my $hash = { ... something different ... } sub _init { my ( $self, %args ) = @_; ... class-specific init code, if needed ... $self->SUPER::_init ( %args ); } 1;

Damian Conway's book Object Oriented Perl (isbn ISBN 1884777791 )is a really terrific tutorial and reference on all things Perl-OO.

Replies are listed 'Best First'.
Re: Re: is this a perversion of OO principles?
by seattlejohn (Deacon) on Jan 07, 2002 at 08:36 UTC
    Thanks for an extremely informative response. I feel much better knowing I'm not the only one using AUTOLOAD like this ;-)

    I agree with you about Damian's book: I just bought it the other day and I'm feeling enlightened already.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-04-19 17:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found