OO范例和Perl5中的封装实例变量

时间:2016-03-06 14:48:35

标签: perl oop variables instance perl5

我需要一种方法在Perl中制作真正封装的变量,而不使用像Moose这样的任何框架,这样你就可以只通过getter和setter来访问实例变量了。应该有私有实例变量。

子例程和方法分别不是问题,因为您可以定义它们,以便它们可以仅通过实例或引用来使用。但是,您始终可以通过包名称访问变量,例如class-vars。

有没有办法阻止它?

3 个答案:

答案 0 :(得分:3)

听起来你试图阻止人们访问除了通过访问器之外的实例变量;是吗?

Perl是礼貌用户的一种语言,你阻止程序员做你不希望他们做的事情的方式就是要求他们不要这样做。是的,有黑客攻击,这里最明显的就是让每个对象成为一个闭包(here's an article about it from the Perl Journal),但几乎总有办法解决它们,所以你将无法阻止那些坚定无礼的黑客< / p>

Larry Wall's excellent attributions中的一个就是这个,这极好地解释了我的观点

  

Perl对强制隐私没有迷恋。因为你没有被邀请,所以你宁愿呆在客厅外面,也不是因为它有霰弹枪

答案 1 :(得分:2)

人们试图用内部对象来实现这种事情。 This presentation by David Golden完美地解释了这一点:

  
      
  • 荷兰Perl黑客阿比盖尔于2002年首次提出的内外对象

  •   
  • 2002年春季 - 在Amsterdam.pm首次提及,

  •   
  • 2002年6月28日 - YAPC NA&#34;两种替代方式做OO&#34;

  •   
  • 2002年7月1日 - 关于Perlmonks的第一次提及

  •   
  • 最近关注(臭名昭着?)作为Damian Conway出版的Perl最佳实践

  • 的推荐最佳实践   
  • 尽管它们有好处,但它们带来了极大的复杂性,并且不受欢迎

  •   

有一个number of modules试图促进这种类型的编程。

我发现它们相当繁琐,而且它们已经失宠了。

您还可以在perldoc perlobj中找到它们:

  

在过去,Perl社区尝试了一种称为&#34;内外对象&#34;的技术。内向外对象将其数据存储在对象的引用之外,索引在对象的唯一属性(例如其内存地址)上,而不是在对象本身中。这具有强制对象属性的封装的优点,因为它们的数据不存储在对象本身中。

     

这种技术很受欢迎(并且在Damian Conway的Perl最佳实践中被推荐),但从未实现过普遍采用。 CPAN上的Object::InsideOut模块提供了这种技术的全面实现,您可以在野外看到它或其他由内到外的模块。

答案 2 :(得分:-2)

要做真正的私有变量,你应该使用闭包:

{
    my $x;

    sub get {
        return $x;
    }

    sub set {
        $x =  shift;
    }
}

set( 3 );
print get(); # prints 3
print $x; # ERROR

# Example with objects
package Class;

sub new {
    bless {}, 'Class';
}
{
    my $storage =  {};

    sub get {
        $self =  shift;
        return $storage->{ "$self" };            
    }

    sub set {
        $self =  shift;
        $storage->{ "$self" } =  shift;
    }
}

package main;
print Class::x; #ERROR

$z = Class::new();
$z->set( 3 );

$y = Class::new();
$y->set( 5 );
print $y->get(); # 5
print $z->get(); # 3

$x是块的本地。除setget之外无其他人可以访问它 “$ self”将类似于“Class = HASH(0x1cf9160)”。因为每个对象在内存中都有自己的地址“$ self”永远不会碰撞。

但实际上,在其他情况下你不需要这样做你的车轮中的一根棍子