Perl派生类继承遗留基类时报Attempt to bless into a reference错误如何解决
错误原因
你遇到的Attempt to bless into a reference报错,根源是基类Base的构造方法被调用时,传入的第一个参数是已完成bless的派生类对象引用,而bless操作的第二个参数要求为类名字符串,传入引用就会触发该错误。
完整执行流程:
- 调用
new derived(top=>"t1")时,派生类derived的new方法接收到的第一个参数为类名字符串derived - 进入
unless (ref $this)分支,fields::new($this)会生成一个已经bless为derived类的受限hash对象,赋值给$this - 执行
$this->Base::new(%arg)时,Perl方法调用会自动把调用者$this(已bless的引用)作为第一个参数传入基类Base的new方法 - 基类
new中的$class变量此时为已bless的对象引用,执行bless $self, $class时直接触发报错
解决方案
因为基类无法修改,你需要调整派生类的构造逻辑,避免将对象引用作为类名传入基类构造,修正后的派生类代码如下:
package derived; use base qw{Base}; use fields qw{_bot}; sub new { my ($class, %arg) = @_; # 以类名调用基类构造,拿到初始化完成的基类对象 my $base_instance = $class->SUPER::new(%arg); # 初始化fields要求的派生类受限hash对象 my __PACKAGE__ $this = fields::new($class); # 复制基类所有已赋值属性到派生类对象 foreach my $attr (keys %$base_instance) { $this->{$attr} = $base_instance->{$attr}; } # 可在此处添加派生类自有属性的初始化逻辑 return $this; } 1;
修改后代码逻辑完全兼容原有基类的属性初始化规则,同时支持fields语法的派生类属性声明和访问校验。
内容的提问来源于stack exchange,提问作者Debabrata Bardhan
相关产品推荐
相关产品推荐

