【发布时间】:2012-06-08 13:12:54
【问题描述】:
我正在尝试从 PHP 中移植一些代码,这些代码基本上可以归结为 property overloading。也就是说,如果您尝试获取或设置一个实际上未定义为类的一部分的类属性,它将将该信息发送到一个函数,该函数几乎可以用它做任何我想做的事情。 (在这种情况下,我想在放弃之前搜索类中的关联数组。)
然而,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 能够以某种方式处理它。
【问题讨论】:
-
Perl 类不是散列,它们只是包。 Perl 对象也不是散列,尽管它们通常是散列到一个包中。
-
展示一点 PHP 代码怎么样?我不完全确定我理解你的意图。
-
it is a very important concept of OOP, I fully expect Perl to handle it somehow.确实如此,但 getter/setter 方法 也是如此,正如@pilcrow 所提到的,可以使用绑定哈希来实现您想要的语法,但这并不能使OOP,事实上 Perl 可以满足这种需求,这归功于 Perl 的灵活性;您仍然应该检查为什么要强制不正确的用法正常工作。 -
@DigitalMan,我看到您的编辑已被回滚。去吧,别理我。如果您是这样的专家,请务必为所欲为。我只是对你的语气感到愤怒。 Perl 提供了重载散列键访问的工具。其他用户不应尝试这样做,但应遵循标准的 OO 协议,因为它们允许正确继承并避免认知失调。我不认为我是上帝,远非如此;但是你的语气并没有引发富有成效的讨论。
标签: perl oop overloading getter-setter