package My::App;
use strict;
use warnings;
use base qw(CGI::Application BLL::OtherPackage);
sub setup {
my $self = shift;
$self->mode_param('section');
$self->start_mode('home');
$self->run_modes(
'here_sub' => 'here_sub',
'test_rm' => 'sub_in_other_file',
);
}
sub here_sub {
my $self = shift;
# no problems using self here
}
1;
### Separate file
package BLL::OtherPackage;
use strict;
use warnings;
sub sub_in_other_file {
my $self = shift;
# $self would be what I expected if I didn't put this in
# the 'use base' or @ISA for that matter. What an abuse.
}
1;
As a long time programer of Perl I feel that this is something that I shouldn't be doing and that there is a correct (and better) way of getting a subroutine's $self to behave as if it were a method of a class even though it's in a separate file. I feel like I am doing something completely wrong. What is the best way to fix this and have methods to a class organised and separated in to separate files? I have Damian Conway's Object oriented Perl but it really hasn't given me any ideas as to how to deal with this.
For example, drop BLL::OtherPackage from your use base list, but use it instead like this:
package My::App; use strict; use warnings; use base qw(CGI::Application); use BLL::OtherPackage qw( sub_in_other_file );Then change BLL::OtherPackage so it exports:
package BLL::OtherPackage;
use strict;
use warnings;
use base 'Exporter';
our @EXPORT_OK = qw( sub_in_other_file );
sub sub_in_other_file {
my $self = shift;
# $self would be what I expected if I didn't put this in
# the 'use base' or @ISA for that matter. What an abuse.
}
1;
In closing, I urge you not to guilty when you use Perl features to get your job done.
Phil
Not that I have a better idea right now. :-(
It doesn't matter if BLL::OtherPackage is used elsewhere. The exporting code runs as many times as is required. If you say use BLL::OtherPackage qw( ... ) then an import call will occur. Period. BLL::OtherPackage is only compiled once but that's ok because you shouldn't need to keep recompiling it.
⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊
I think philcrow has a good idea above. Basically you want to treat these files as if they are CGI::Application plugins. However, this solution is not without it's issues (exported methods conflicting, or overriding inherited methods, etc etc etc).
As for the "is this good OO", the answer IMO is yes (kind of). What you are doing here is not all that different from what Perl 6 Roles try to do, which is to break down classes one step further. A role is not a class, but instead a collection of reusable methods which can be "injected" into a class's namespace.
At $work, we have been experimenting with using Moose and more specifically Moose::Role for this type of problem. We have a base CGI::Application subclass which we all our applications inherit from, then we have a set of common roles which we can then add to our application. The roles include things like configuration file management, DBIx::Class schema setup and management, request logging and a number of other items which are useful in most (but not all) applications.
And if you don't want to use Moose, you could also look into the other Role modules on CPAN. I would recommend Perl6::Roles or Class::Trait, with Class::Trait being the more "full-featured" of the two.
perlmonks.org content © perlmonks.org and BMaximus, diotalevi, girarde, philcrow, stvn
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03