gpt4 book ai didi

perl - 为什么perl对象实例会互相覆盖

转载 作者:行者123 更新时间:2023-12-01 07:19:32 25 4
gpt4 key购买 nike

我编写了一些 Perl 代码,这些代码由一个基础类所固有的两个类组成。我想它会打印这样的东西

Mik: Meow! Meow!
Sat: Woof! Woof!

但它实际上是这样打印的:

Sat: Woof! Woof!
Sat: Woof! Woof!

,

package Animal;
sub new {

my $obj = shift;
my $name = shift;
our %pkg = ( 'name' => $name );
bless \%pkg, $obj;
return \%pkg;
}

package Cat;
@ISA = ("Animal");

sub new {
my $obj = shift;
my $name = shift;
my $self = $obj->SUPER::new($name);
return $self;
}

sub get_name {
my $obj = shift;
return $obj->{'name'};
}


sub talk {
my $obj = shift;
return "Meow! Meow!";
}

package Dog;
@ISA = ("Animal");

sub new {
my $obj = shift;
my $name = shift;
my $self = $obj->SUPER::new( $name );
return $self;
}

sub get_name {
my $obj = shift;
return $obj->{'name'};
}

sub talk {
my $obj = shift;
return "Woof! Woof!";
}

package Main;

my $cat = new Cat('Mike');
my $dog = new Dog('Sat');

print $cat->get_name() . ": " . $cat->talk() , "\n";
print $dog->get_name() . ": " . $dog->talk() , "\n";

但是如果我以这种方式更改调用者,它会打印出我认为的内容。所以很奇怪为什么$dog实例化后$cat对象被覆盖了?

package Main;

my $cat = new Cat('Mily');
print $cat->get_name() . ": " . $cat->talk() , "\n";

my $dog = new Dog('Sat');
print $dog->get_name() . ": " . $dog->talk() , "\n";

最佳答案

为什么要bless成一个全局变量?将您的构造函数更改为:

sub new {
my $obj = shift;
my $name = shift;
my %pkg = ( 'name' => $name );
bless \%pkg, $obj;
return \%pkg;
}

更好的是,将其更改为更惯用的内容:

sub new {
my $class = shift;
my $name = shift;
my $self = { name => $name };
return bless $self, $class;
}

继续:

为什么要在每种动物中实现newget_name?这两种方法都可以继承。当我们这样做的时候,我们也可以摆脱 @ISA 的困惑:

package Animal;
sub new {
my $class = shift;
my $name = shift;
my $self = { name => $name };
return bless $self, $class;
}

sub get_name {
my $self = shift;
return $self->{'name'};
}

package Cat;
use base qw/ Animal /;

sub talk {
my $self = shift;
return "Meow! Meow!";
}

package Dog;
use base qw/ Animal /;

sub talk {
my $self = shift;
return "Woof! Woof!";
}

package Main;

my $cat = Cat->new('Mike');
my $dog = Dog->new('Sat');

print $cat->get_name() . ": " . $cat->talk() , "\n";
print $dog->get_name() . ": " . $dog->talk() , "\n";

请问您正在学习哪本教程或书籍?

虽然上面的内容非常好,但您也可以使用现代 Perl 方式:

package Animal;
use Moose;
has name => ( required => 1, is => 'rw', isa => 'Str' );

package Cat;
use Moose;
extends 'Animal';

has talk => ( default => "Meow! Meow!", is => 'ro' );

package Dog;
use Moose;
extends 'Animal';

has talk => ( default => "Woof! Woof!", is => 'ro' );

package Main;
my $cat = Cat->new( name => 'Mike');
my $dog = Dog->new( name => 'Sat');

print $cat->name . ": " . $cat->talk , "\n";
print $dog->name . ": " . $dog->talk , "\n";

关于perl - 为什么perl对象实例会互相覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17472783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com