Jar*_*und 8 oop perl coding-style perl5
标题几乎总结了,但无论如何这里是长版本.
在发布了一小段perl代码之后,我被告知要避免使用间接对象表示法,"因为它有几个副作用".评论引用了这一特定的行:
my $some_object = new Some::Module(FIELD => 'value');
Run Code Online (Sandbox Code Playgroud)
因为这就是我一直以来的做法,为了与时俱进,我因此问:
我正要问这位评论者,但对我而言,这是值得发表的.
cjm*_*cjm 18
主要问题是它含糊不清.是否
my $some_object = new Some::Module(FIELD => 'value');
Run Code Online (Sandbox Code Playgroud)
意味着调用包中的new方法Some::Module,还是意味着调用new当前包中的Module函数,结果是Some使用给定的参数调用包中的函数?
即,它可以被解析为:
# method call
my $some_object = Some::Module->new(FIELD => 'value');
# or function call
my $some_object = new(Some::Module(FIELD => 'value'));
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用显式方法调用表示法Some::Module->new(...).
通常,解析器会正确猜测,但最佳做法是避免歧义.
这有什么不好的?
间接方法表示法的问题是可以避免的,但是告诉人们避免间接方法表示法要容易得多.
主要问题是很容易意外地调用错误的功能.请使用以下代码,例如:
package Widget;
sub new { ... }
sub foo { ... }
sub bar { ... }
sub method {
...;
my $o = new SubWidget;
...;
}
1;
Run Code Online (Sandbox Code Playgroud)
在该代码中,new SubWidget预计意味着
SubWidget->new()
Run Code Online (Sandbox Code Playgroud)
相反,它实际上意味着
new("SubWidget")
Run Code Online (Sandbox Code Playgroud)
也就是说,使用strict将捕获大多数此错误的实例.如果use strict;要添加到上面的代码段,将产生以下错误:
Bareword "SubWidget" not allowed while "strict subs" in use at Widget.pm line 11.
Run Code Online (Sandbox Code Playgroud)
也就是说,有些情况下使用strict不会发现错误.它们主要涉及在方法调用的参数周围使用parens(例如new SubWidget($x)).
这意味着
前者是可以忍受的,而后者是可以避免的.但是,我们只是告诉人们"避免使用间接方法表示法",而不是告诉人们"避免在使用间接方法表示法的方法调用的参数周围使用parens".它太脆弱了.
还有另一个问题.这不仅仅是使用间接对象表示法这是一个问题,它在Perl中支持它.该特征的存在导致多个问题.首先,
从好的方面来说,使用no indirect;有助于解决第一个问题.
应该如何重写该行?
编写方法调用的正确方法如下:
my $some_object = Some::Module->new(FIELD => 'value');
Run Code Online (Sandbox Code Playgroud)
也就是说,即使这种语法也不明确.它将首先检查名为的函数是否Some::Module存在.但这种情况非常不可能,很少有人能够保护自己免受此类问题的影响.如果您想保护自己,可以使用以下内容:
my $some_object = Some::Module::->new(FIELD => 'value');
Run Code Online (Sandbox Code Playgroud)
至于如何避免它:有一个CPAN模块禁止表示法,就像一个pragma模块:
no indirect;
Run Code Online (Sandbox Code Playgroud)
http://metacpan.org/pod/indirect
| 归档时间: |
|
| 查看次数: |
356 次 |
| 最近记录: |