有人可以告诉我为什么在这个非常小而琐碎的示例中main无法找到Class::Accessor生成的方法吗?

这几行代码因

perl codesnippets/accessor.pl
Can't locate object method "color" via package "Critter" at
codesnippets/accessor.pl line 6.

看代码:
#!/opt/local/bin/perl
# The whole Class::Accessor thing does not work !!

my $a = Critter->new;
$a->color("blue");
$a->display;
exit 0;

package Critter;
    use base qw(Class::Accessor );
    Critter->mk_accessors ("color" );

    sub display {
        my $self  = shift;
        print "i am a $self->color " . ref($self) . ", whatever this word means\n";
    }

最佳答案

FM给您很好的建议。 mk_accessors需要在其他代码之前运行。同样,通常您将Critter放在一个单独的文件中,然后将use Critter放在一个模块中。

这是有效的,因为use具有编译时间效果。进行use Critter;与执行BEGIN { require Critter; Critter->import; }相同。这保证了模块的初始化代码将在其余代码甚至编译之前运行。

将多个软件包放在一个文件中是可以接受的。通常,我会在一个文件中对相关对象进行原型(prototype)设计,因为在进行原型(prototype)设计时,它使一切工作变得很方便。时间到了,将文件分成几个单独的部分也很容易。

因此,我发现将多个软件包保存在一个文件中并像使用它们一样使用它们的最佳方法是将软件包定义放在以真值结尾的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;
}

关于Perl Class::Accessor失败,简单的例子-为什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2973549/

10-12 23:09