当前位置:  开发笔记 > 编程语言 > 正文

如何在Perl模块中创建私有函数?

如何解决《如何在Perl模块中创建私有函数?》经验,为你挑选了5个好方法。

我正在研究一个小的Perl模块,由于某种原因,我有一个测试驱动程序脚本,它使用我的新模块调用我认为是私有的函数之一,并且它是成功的.我很惊讶,所以我开始搜索谷歌,我真的找不到任何关于如何在Perl模块中创建私有函数的文档...

我看到一个地方说要在你的"私人"功能的右大括号之后加一个分号,如下所示:

sub my_private_function {
...
}; 

我尝试过,但我的驱动程序脚本仍然可以访问我想要私有的功能.

我会做一些简短的例子,但这就是我所追求的:

模块TestPrivate.pm:

package TestPrivate;

require 5.004;

use strict;
use warnings;
use Carp;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);

require Exporter;

@ISA = qw(Exporter AutoLoader);

our @EXPORT_OK = qw( public_function );
our @EXPORT    = qw( );

$VERSION = '0.01';

sub new {
    my ( $class, %args ) = @_;
    my $self = {};
    bless( $self, $class );
    $self->private_function("THIS SHOULD BE PRIVATE");
    $self->{public_variable} = "This is public";
    return $self;
}

sub public_function {
    my $self     = shift;
    my $new_text = shift;
    $self->{public_variable} = $new_text;
    print "Public Variable: $self->{public_variable}\n";
    print "Internal Variable: $self->{internal_variable}\n";
}

sub private_function {
    my $self     = shift;
    my $new_text = shift;
    $self->{internal_variable} = $new_text;
}

驱动程序:TestPrivateDriver.pl

#!/usr/bin/perl
use strict;
use TestPrivate 'public_function';
my $foo = new TestPrivate();
$foo->public_function("Changed public variable");
$foo->private_function("I changed your private variable");
$foo->public_function("Changed public variable again");
$foo->{internal_variable} = "Yep, I changed your private variable again!";
$foo->public_function("Changed public variable the last time");

驱动输出:

Public Variable: Changed public variable
Internal Variable: THIS SHOULD BE PRIVATE
Public Variable: Changed public variable again
Internal Variable: I changed your private variable
Public Variable: Changed public variable the last time
Internal Variable: Yep, I changed your private variable again!

所以我在模块中的最后一个右大括号之后添加了一个分号,但输出仍然是相同的.我真正找到的唯一一件事就是将这一行添加为private_function的第一行:

caller eq __PACKAGE__ or die;

但这看起来很糟糕.我没有很多编写Perl模块的经验,所以也许我正在设置我的模块错误?是否可以在perl模块中使用私有函数和变量?

谢谢你帮我学习!



1> jedihawk..:

perldoc perltoot(大约四分之一的文件):

Perl没有对谁使用哪种方法施加限制.公共与私人的区别是按惯例,而不是语法.(好吧,除非您使用下面"数据成员作为变量"中描述的Alias模块.)有时您会看到以下划线或下划线开头或结尾的方法名称.此标记是一种约定,表示方法仅对该类是私有的,有时对其最近的熟人(其直接子类)是私有的.但Perl本身并没有强制执行这种区分.这取决于程序员的行为.

因此,我建议您在"私人"方法的开头加上一个或两个下划线,以帮助阻止使用.


"Undersore"?可爱的形象.
从Perl 5.18开始,您可以使用“ my”或“ state”声明一个私有子例程。https://perldoc.perl.org/perlsub.html#Lexical-Subroutines

2> Axeman..:

只有"The Kludge"将代码引用存储在词法变量中,该范围之外的任何人都看不到:

my $priv_func1 = sub { my $self = shift; say 'func1'; };

sub public_sub { 
    my $self = shift;

    $priv_func1->( $self );
}

而且我想不出一种方法来制造严格的"受保护"字段.

就我所知,这就是它(除了源代码过滤器......嘘.我没有提到它们......)


编辑:事实上,事实证明,我可以想到一个非常混乱的做保护方式.但它可能涉及通过AUTOLOAD子传递所有呼叫.(!!)



3> Leon Timmerm..:

这有效:

my $priv_func1 = sub {
    my $self = shift; say 'func1';
};

sub public_sub { 
    my $self = shift;

    $self->$priv_func1(@_);
}


以太:你完全错了,事实上它更有效率,因为它不需要方法查找.

4> JDrago..:

只需检查来电者:

package My;

sub new {
  return bless { }, shift;
}

sub private_func {
  my ($s, %args) = @_;
  die "Error: Private method called"
    unless (caller)[0]->isa( ref($s) );

  warn "OK: Private method called by " . (caller)[0];
}

sub public_func {
  my ($s, %args) = @_;

  $s->private_func();
}

package main;

my $obj = My->new();

# This will succeed:
$obj->public_func( );

# This will fail:
$obj->private_func( );



5> brian d foy..:

你想做什么?也许有更好的Perl方式来做你想要完成的任何事情.

例如,如果您不希望人们因为您想要强制执行封装而在您的对象中乱逛,您可以使用类似Class :: InsideOut的东西.该模块有一个Class :: InsideOut :: About文档模块,解释了这个概念.还有一些Object :: InsideOut,Brian Phillips已经提到过.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有