我试图从 PHP 中移植一些基本上归结为属性重载的代码。也就是说,如果您尝试获取或设置一个实际上未定义为类的一部分的类属性,它将将该信息发送到一个函数,该函数几乎可以用它做任何我想做的事情。(在这种情况下,我想在放弃之前搜索类中的关联数组。)
然而,Perl 与 PHP 有很大的不同,因为类已经是散列了。有什么方法可以将某种等价物应用__get()
到__set()
Perl“类”,该类将完全封装在该包中,对任何试图实际获取或设置属性的东西都是透明的?
编辑:解释这一点的最好方法可能是向您展示代码,显示输出,然后显示我希望它输出的内容。
package AccessTest;
my $test = new Sammich; #"improper" style, don't care, not part of the question.
say 'bacon is: ' . $test->{'bacon'};
say 'cheese is: ' . $test->{'cheese'};
for (keys $test->{'moreProperties'}) {
say "$_ => " . $test->{'moreProperties'}{$_};
}
say 'invalid is: ' . $test->{'invalid'};
say 'Setting invalid.';
$test->{'invalid'} = 'true';
say 'invalid is now: ' . $test->{'invalid'};
for (keys $test->{'moreProperties'}) {
say "$_ => " . $test->{'moreProperties'}{$_};
}
package Sammich;
sub new
{
my $className = shift;
my $this = {
'bacon' => 'yes',
'moreProperties' => {
'cheese' => 'maybe',
'ham' => 'no'
}
};
return bless($this, $className);
}
这当前输出:
bacon is: yes
Use of uninitialized value in concatenation (.) or string at ./AccessTest.pl line 11.
cheese is:
cheese => maybe
ham => no
Use of uninitialized value in concatenation (.) or string at ./AccessTest.pl line 17.
invalid is:
Setting invalid.
invalid is now: true
cheese => maybe
ham => no
现在,我只需要对Sammich 进行修改,而无需对初始 AccessTest 包进行任何更改,这将导致:
bacon is: yes
cheese is: maybe
cheese => maybe
ham => no
invalid is: 0
Setting invalid.
invalid is now: true
cheese => maybe
ham => no
invalid => true
正如你所看到的,想要的效果是'cheese'属性,因为它不是直接测试对象的一部分,而是从'moreProperties'哈希中获取。'invalid' 会尝试同样的事情,但由于它既不是直接属性也不是在 'moreProperties' 中,它会以任何编程方式运行 - 在这种情况下,我希望它简单地返回值 0,没有任何错误或警告。在尝试设置“无效”属性时,它不会直接添加到对象中,因为它还不存在,而是会添加到“更多属性”哈希中。
我希望这比 PHP 中需要的六行多,但由于它是 OOP 的一个非常重要的概念,我完全希望 Perl 能够以某种方式处理它。