处理用户不会调用的方法的正确方法是什么?例如,如果用户调用方法,从驱动程序脚本中说出do_stuff()
,并且如果do_stuff()
依赖于其他子例程,那么最好从do_stuff()
方法中调用这些子方法作为如下:
sub do_stuff {
my ( $self, %arg ) = @_;
#does it things
#and then calls the private sub as follows
_private_sub( $self, %arg );
}
答案 0 :(得分:4)
据我所知,没有"正确"办法。 Perl并没有提供隐藏功能的能力,至少我曾遇到过这种功能。我所做的是使用一个命名标准,我用一个下划线启动仅限内部的函数名称,并清楚地记录它们永远不会被外部调用者调用。
编辑:其他答案引发了一个想法。在每个私有方法中,您可以检查"调用者()"的结果。如果调用者是本地模块以外的任何人,则函数和中止。老实说,我个人不会遇到麻烦,但如果由于某些原因它对你来说真的很重要,那就会强调这些方法的私密性。
答案 1 :(得分:3)
如果您的do_stuff
方法需要您应该保留的功能,那么#34;私有"然后一定要在其中调用_private_sub
。这正是它的目的。当然,拥有一个私人"私人"是一个惯例问题,因为它无法执行。
我想提一下使用私有子代码
的代码my $_private = sub { ... }; # must be at least predeclared
sub do_stuff {
my ($self, %arg) = @_;
# ...
my $from_private = $self->$_private->(@args); # or
my $more_private = $_private->($self, @args);
}
语法很奇怪,但肯定警告用户它是私有方法。这使得子类很难继承,这要归功于mob强调这一点。
第二次调用使用$_private
作为函数而不是方法,因此我们必须在需要时传递对象。这进一步警告不要使用它。然后它也没有经历正常的方法查找过程(因此稍快一点),这是一个很清楚的事情。
我对这个问题究竟是什么有点不确定。
如果是关于是否使用"私人"你的代码中的子程序,然后真的没有公认的最佳实践。它们非常有用,但它们并非真正私密。我自由地使用它们。
答案 2 :(得分:1)
与$self->_private_sub(...)
相反?在我看来,$obj->_method
符号总是与作用于类实例的函数一起使用,其他类型的调用总是用于其他类型的函数。
但是,如果你是偏执狂,为什么不使用一种非传统的方式来填充你的论点,这会让那些试图以面向对象的方式使用私有方法的人感到困惑呢?
sub do_stuff {
my ( $self, %arg ) = @_;
...
_private_sub( %arg, $self );
}
sub _private_sub {
my $self = pop;
my %args = @_;
...
}
答案 3 :(得分:1)
到目前为止,您收到的所有答案都表示无法完成。但它可以 - 在Perl 5.18及更高版本中。请参阅section on lexical subroutines in perldoc perlsub
。
词汇子程序
警告:词法子程序仍处于试验阶段。在将来的Perl版本中可能会修改或删除该功能。
词法子程序仅在
let boston: [String: Any] = ["title": "Boston, MA", "latitude": 39.713054, "longitude": -88.632398] locations.append(boston)
编译指示下可用,它会产生警告,除非" experimental :: lexical_subs"警告类别已禁用。从Perl 5.18开始,您可以使用
use feature 'lexical_subs'
或my
声明私有子例程。与状态变量一样,州关键字仅在state
或use feature 'state'
或更高版本下可用。这些子例程仅在声明它们的块中可见,并且仅在声明之后:
use 5.010
要从子程序本身内部使用词法子程序,必须预先声明它。
no warnings "experimental::lexical_subs"; use feature 'lexical_subs'; foo(); # calls the package/global subroutine state sub foo { foo(); # also calls the package subroutine } foo(); # calls "state" sub my $ref = \&foo; # take a reference to "state" sub my sub bar { ... } bar(); # calls "my" sub
子例程定义语法尊重任何先前的sub foo {...}
或my sub;
声明。state sub;