加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl Moose类中的私有变量

发布时间:2020-12-16 06:17:58 所属栏目:大数据 来源:网络整理
导读:我开始使用Moose了解Perl中的对象. 我不确定我是否理解MooseX :: Privacy的目的.考虑: use v5.14;package PA { use Moose; my $var='private?'; 1; sub getVar { return $var; }}package PB { use Moose; use MooseX::Privacy; has 'var' = ( is = 'rw',isa
我开始使用Moose了解Perl中的对象.

我不确定我是否理解MooseX :: Privacy的目的.考虑:

use v5.14;

package PA {
    use Moose;
    my $var='private?';
    1;

    sub getVar {
        return $var;
    }
}

package PB {
    use Moose;
    use MooseX::Privacy;

    has 'var' => (
        is => 'rw',isa => 'Str',default   => 'private?',traits => [qw/Private/],);
    1;

    sub getVar {
        my $self = shift;
        return $self->var;
    }
}

my $o1= PA->new();
my $o2= PB->new();

say $o1->getVar();
say $o2->getVar();

在PA和PB类中,我有一个私有变量var.仅在PB类中我使用MooseX :: Privacy.这两种方法有什么区别?我为什么要使用MooseX :: Privacy?

解决方法

如果您正在寻找Java风格的方法隐私,那么MooseX :: Privacy将会非常令人失望.以下是Java样式方法隐私的情况:

/* This file is called Main.java */
public class Main
{
    public class MyParent
    {
        private String message_string ()
        {
            return "Message from %sn";
        }

        public void print_message ()
        {
            System.out.printf( this.message_string(),"MyParent" );
        }
    }

    public class MyChild extends MyParent
    {
        public String message_string ()
        {
            return "Another message from %sn";
        }
    }

    public static void main (String[] args)
    {
        Main o = new Main();
        o.run();
    }

    public void run ()
    {
        MyParent c = new MyChild();
        c.print_message();
    }
}

您可以像这样编译并运行此示例:

$javac Main.java
$java Main
Message from MyParent

注意发生了什么.父类(MyParent)将message_string()声明为私有方法.子类尝试覆盖该方法,但是被彻底拒绝 – 对于您的子类没有汤!

现在让我们尝试使用Perl和MooseX :: Privacy …

# This file is called Main.pl
use v5.14;
use strict;
use warnings;

package MyParent {
    use Moose;
    use MooseX::Privacy;

    private_method message_string => sub {
        my $self = shift;
        return "Message from %sn";
    };

    sub print_message {
        my $self = shift;
        printf($self->message_string(),__PACKAGE__);
    }
}

package MyChild {
    use Moose; extends qw(MyParent);
    use MooseX::Privacy;

    sub message_string {
        my $self = shift;
        return "Another message from %sn";
    }
}

my $c = new MyChild();
$c->print_message();

我们可以像这样运行:

$perl Main.pl
Another message from MyParent

说,WHA?!?!?! message_string不应该是私有的吗?! MyChild如何覆盖MyParent中的方法?!

事实上,MooseX :: Privacy并没有像大多数面向对象语言那样为您提供方法隐私. MooseX ::隐私就像在你的方法中这样做:

die "GO AWAY!!" unless caller eq __PACKAGE__;

除了MooseX :: Privacy为您的所有方法调用添加了大量的运行时开销.

真的,没有理由使用MooseX :: Privacy.如果你想要私有方法,把它们放在词法变量中.像这样:

use v5.14;
use strict;
use warnings;

package MyParent {
    use Moose;

    my $message_string = sub {
        my $self = shift;
        return "Message from %sn";
    };

    sub print_message {
        my $self = shift;
        printf($self->$message_string(),__PACKAGE__);
    }
}

package MyChild {
    use Moose; extends qw(MyParent);

    sub message_string {
        my $self = shift;
        return "Another message from %sn";
    }
}

my $c = new MyChild();
$c->print_message();

现在运行它:

$perl Main2.pl
Message from MyParent

哈利路亚!我们有一个真正的私人方法!

好的,所以你可以拥有没有MooseX :: Privacy的私有方法,它们比MooseX :: Privacy更好(也更快).

但私有属性呢?好吧,我在CPAN上有一个小模块可以帮助你:Lexical::Accessor.这是一个为你创建属性的小工具,具有“由内而外”的存储(即属性值不会存储在对象的祝福hashref中),并在词法变量中安装它的访问器(就像上面的私有$get_message方法一样).

无论如何,这是我对MooseX :: Privacy的看法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读