BMaximus has asked for the wisdom of the Perl Monks concerning the following question:

In trying to keep my code clean I like separating different functions in to separate modules and then bring them together in to a main module. When using a framework like CGI::Application though, I'm not sure how to do this so that when the functions from other modules are invoked I can pull $self in them as if they were a part of the main class. So far I've done this two ways. The first way is to use Exporter and the other way is to put the module in @ISA. I'm not sure if either one of these methods is a good way to go. So I'd like to know what would be a better way to do what I'm trying to do. Going through the best practices book it says as far as inheritance goes use base. So that's what I'm doing to get the function from other packages in to my main application. So what is the better way to do what I'd like to do?


Replies are listed 'Best First'.
Re: OOP and Methods Question
by philcrow (Priest) on Dec 28, 2005 at 19:00 UTC
    Both use base and modifying @ISA provide genuine inheritence. use base is a newer approach which is a bit cleaner syntactically, but has the same effect as using the module, then putting its name into @ISA.

    Using Exporter amounts to using mixins. This means that the methods don't care what class structure you have so long as the object used to invoke the method responds appropriately.

    Using inheritence is a more generally accepted practice. But Exporting object oriented methods can make good sense too. Ask yourself this: is there a hierarchy of inheritence which makes sense for the app, or are the helper methods more unstructured. If the former inherit, otherwise stick with your Exporter mixins.


Re: OOP and Methods Question
by pajout (Curate) on Dec 28, 2005 at 17:55 UTC
    It depends. If you want to use as library of functions, try this - it supposes that is on the place, which perl seeks for modules:
    package MainModule; use YourModule (); my $ret = YourModule::yourFunction();
    but, if you want to have an object, which inherits from, you can try something as:
    package MyObject; use base 'YourModule'; sub new { ...} my $instance = MyObject->new(); my $ret = $instance->yourFunction();
    and all methods from YourModule will be accessible through $instance.
Re: OOP and Methods Question
by wazzuteke (Hermit) on Dec 28, 2005 at 18:07 UTC
    To add to the above comment, realitve to your question: it all depends on the situation of your application of when you want to use base or @ISA. I have always tried to use base when creating my class hierarchy, however I have also ran into circumstances where I had to use the @ISA array.

    Either solution should work in most cases, though I usually also tell people to try use base first.

    In either curcumstance, if you are to use the @ISA array, I always put it within a BEGIN block. Maybe for personal preference, although it makes sence to ensure the push happens at compile time, rather than run time.
    package MyObject; use strict; use warnings; use vars qw( @ISA ); BEGIN { push( @ISA, 'BaseObject' ); }; sub new { # Code here } # Follow up with some methods 1;
    So, hopefully you can see what I mean here.

    Good luck!

    print map{$_.' '}grep{/\w+/}@{[reverse(qw{Perl Code})]} or die while ( 'trying' );
Re: OOP and Methods Question
by phaylon (Curate) on Dec 28, 2005 at 19:21 UTC
    You could also take a look at Class-Trait. Very useful for separating behaviour when you don't need overloaded methods.

    Ordinary morality is for ordinary people. -- Aleister Crowley