在Perl中,对象通常是对哈希的引用,而“槽”(slots)是哈希中存储对象数据的单独字段。为了节省代码并动态创建方法,通常使用魔术方法 AUTOLOAD。
AUTOLOAD 允许拦截对不存在方法的调用,并动态实现“瞬时”方法。例如,自动生成getter和setter方法:
package MyObj; sub new { bless { foo => 1, bar => 2 }, shift } our $AUTOLOAD; sub AUTOLOAD { my ($self) = @_; my $field = $AUTOLOAD =~ s/.*:://r; die "没有这样的槽 $field" unless exists $self->{$field}; return $self->{$field}; } my $obj = MyObj->new; print $obj->foo; # 1
危险性:
AUTOLOAD与直接定义方法有什么区别?在为所有类访问器使用AUTOLOAD时有哪些缺点?
答案:AUTOLOAD在运行阶段工作,与显式方法不同。通常与错误的方法名相关的错误仅在执行时才会显现,而不是在编译时,因此调试更加困难。错误使用的例子:
$obj->fop; # 而不是foo,导致不会出现编译错误,而是进入AUTOLOAD
最好在编译部分通过eval显式生成方法。
事件
事件
事件
在一个对象序列化库中,方法通过AUTOLOAD自动生成,但是忘记实现特殊的DESTROY,结果在删除对象时触发了AUTOLOAD,出现了关于缺少DESTROY方法的错误并导致内存泄漏。