FM дает вам хороший совет. mk_accessors
необходимо запустить перед другим кодом. Кроме того, обычно вы помещаете Critter
в отдельный файл и use Critter
для загрузки модуля.
Это работает, потому что use
имеет эффекты времени компиляции. Выполнение use Critter;
аналогично выполнению BEGIN { require Critter; Critter->import; }
Это гарантирует, что код инициализации вашего модуля будет запущен до того, как остальная часть кода даже скомпилируется.
Допустимо помещать несколько пакетов в один файл. Часто я создаю прототипы связанных объектов в одном файле, так как он сохраняет все под рукой, пока я создаю прототип. Также довольно легко разбить файл на отдельные части, когда придет время.
По этой причине я считаю, что лучший способ хранить несколько пакетов в одном файле и работать с ними, как если бы я их использовал, - это поместить определения пакетов в BEGIN
блоки, заканчивающиеся истинным значением. Используя мой подход, ваш пример будет написан:
#!/opt/local/bin/perl
my $a = Critter->new;
$a->color("blue");
$a->display;
BEGIN {
package Critter;
use base qw(Class::Accessor );
use strict;
use warnings;
Critter->mk_accessors ("color" );
sub display {
my $self = shift;
# Your print was incorrect - one way:
printf "i am a %s %s whatever this word means\n", $self->color, ref $self;
# another:
print "i am a ", $self->color, ref $self, "whatever this word means\n";
}
1;
}