This is wrong in just so many ways.
Firstly, just scrap all the import/export stuff. It will not do what you want it to do. Exporting and object-oriented programming have nothing to with each other.
There are many people who claim that you ought never do both of them in the same package. I personally wouldn't go that far, but in your example there's really no need for any exporting, and I'd suggest that you lay off trying to combine exporting and OO until you're more comfortable with OO concepts.
Secondly, a related issue: this eval "require Person::Baby"; import Person::Baby; stuff ain't gonna work. You appear to be wanting to set up something like per-object inheritance. Not gonna happen. Inheritance in Perl happens on a per-class basis; not per-object. However, you may be able to accomplish what you want using run-time application of roles to objects. (See Role::Tiny, Moo::Role, Moose::Role, etc.)
Thirdly, you're blessing most of your objects incorrectly. As an example, you have a package called "Person::Adult", but then bless objects into a package called just "Adult".
I don't know how to continue. But there is plenty of other weird stuff you're doing. Please find a tutorial on OO Perl. You won't find any mention of all this import/export stuff. Pick up a copy of chromatic's book Modern Perl; IIRC is has some good stuff on OO programming. The Kindle edition costs but a few beans; the printed edition slightly more; but chromatic makes the HTML and PDF versions available online for free, so you can't say fairer than that, can you?
Anyway, here's how I'd do it using Moo and Moo::Role...
use v5.10; use strict; use warnings; { package Person; use Moo; has name => (is => 'ro', default => 'erere'); has age => (is => 'ro', default => 233); sub BUILD { my $self = shift; if ($self->age < 20) { 'Moo::Role'->apply_roles_to_object($self, 'Person::Baby'); } else { 'Moo::Role'->apply_roles_to_object($self, 'Person::Adult') +; } } sub sayHello { my $self = shift; say "Hello from ", $self->name; } } { package Person::Baby; use Moo::Role; around sayHello => sub { shift; my $self = shift; say "Goo-goo, gaa-gaa from ", $self->name; }; } { package Person::Adult; use Moo::Role; } my $alice = 'Person'->new(name => 'Alice', age => 0.5); my $bob = 'Person'->new(name => 'Bob', age => 50); for my $person ($alice, $bob) { if ($person->isa('Person')) { say $person->name, " is a 'Person'!"; } if ($person->DOES('Person::Adult')) { say $person->name, " does the 'Person::Adult' role!"; } if ($person->DOES('Person::Baby')) { say $person->name, " does the 'Person::Baby' role!"; } $person->sayHello; say "----"; } say "Now let's look at the employees!"; { package Employee; use Moo; extends 'Person'; has dept => (is => 'ro', default => 'Administrative Affairs'); sub BUILD { my $self = shift; if ($self->dept eq 'IT') { 'Moo::Role'->apply_roles_to_object($self, 'Employee::IT'); } elsif ($self->dept eq 'Finance') { 'Moo::Role'->apply_roles_to_object($self, 'Employee::Finan +ce'); } } } { package Employee::IT; use Moo::Role; sub fixComputer { my $self = shift; say "Happy to help!"; } } { package Employee::Finance; use Moo::Role; sub payOtherEmployees { my $self = shift; for my $other (@_) { next unless $other->isa('Employee'); say $self->name, " pays ", $other->name; } } } my $carol = 'Employee'->new(name => 'Carol', dept => 'IT', age => 40); my $dave = 'Employee'->new(name => 'Dave', dept => 'IT', age => 19); my $eve = 'Employee'->new(name => 'Eve', dept => 'Finance', age => 5 +8); for my $person ($carol, $dave, $eve) { if ($person->isa('Person')) { say $person->name, " is a 'Person'!"; } if ($person->isa('Employee')) { say $person->name, " is an 'Employee'!"; } if ($person->DOES('Person::Adult')) { say $person->name, " does the 'Person::Adult' role!"; } if ($person->DOES('Person::Baby')) { say $person->name, " does the 'Person::Baby' role!"; } if ($person->DOES('Employee::IT')) { say $person->name, " does the 'Employee::IT' role!"; $person->fixComputer; } if ($person->DOES('Employee::Finance')) { say $person->name, " does the 'Employee::Finance' role!"; } $person->sayHello; say "----"; } # Were Alice and Bob employees? $eve->payOtherEmployees($alice, $bob, $carol, $dave);
Lastly, 19 year olds generally don't appreciate being referred to as babies.
Update: if you wanted to split the packages out into separate files, then you'd need to make sure they're all loaded...
One technique would be to load them up front using use statements. For example, the Person package clearly makes use of the Person::Adult and Person::Baby packages, so could be written as:
package Person; use Moo; use Person::Adult; use Person::Baby; has name => (is => 'ro', default => 'erere'); has age => (is => 'ro', default => 233); sub BUILD { my $self = shift; if ($self->age < 20) { 'Moo::Role'->apply_roles_to_object($self, 'Person::Baby'); } else { 'Moo::Role'->apply_roles_to_object($self, 'Person::Adult'); } } sub sayHello { my $self = shift; say "Hello from ", $self->name; } 1;
An alternative technique would be to load them at run time with require. This has the advantage that if, say, you never instantiated a Person with an age below 20, the Person::Baby role would never get loaded at all, cutting down on the amount of time Perl had to spend compiling your script. If you've got a lot of roles, some of which are rarely used, then this can be a useful optimization technique.
package Person; use Moo; has name => (is => 'ro', default => 'erere'); has age => (is => 'ro', default => 233); sub BUILD { my $self = shift; if ($self->age < 20) { require Person::Baby; 'Moo::Role'->apply_roles_to_object($self, 'Person::Baby'); } else { require Person::Adult; 'Moo::Role'->apply_roles_to_object($self, 'Person::Adult'); } } sub sayHello { my $self = shift; say "Hello from ", $self->name; } 1;
In reply to Re: Can't locate object method- Issue
by tobyink
in thread Can't locate object method- Issue
by perl_noobie
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |