在Perl中,创建与程序包同名的子例程是否有害?

问题描述

| 假设我有一个名为
My::Pkg
的包,并且该包具有
->new(...)
类方法来实例化新对象:
package My::Pkg;

sub new {bless {@_[1..$#_]} => $_[0]}
定义以下子例程是否有任何危害:
sub My::Pkg {@_ ? My::Pkg::new(\'My::Pkg\',@_) : \'My::Pkg\'}
这样有人可以写:
my $obj = My::Pkg one => 1,two => 2;
而不是:
my $obj = My::Pkg->new(one => 1,two => 2); # which still works,but is longer
我喜欢package-named-constructor-subroutine方法的简洁性,但是我很想知道这种技术是否存在我从未想过的隐患。 更新: 继承可以正常工作,如此处的示例所示:
{package a; sub new {say \"a::new [@_] \",$_[0]->init}}
{package b;    our @ISA = \'a\'; sub init {\"(b::init [@_])\"}}
{package a::b; our @ISA = \'b\';}

sub a::b {print \"absub [@_],\"; \'a::b\'}

# a::b() called with no args,returns \'a::b\',which then becomes \'a::b\'->new(...)
a::b->new;            # absub [],a::new [a::b] (b::init [a::b])
a::b->new(1,2,3);   # absub [],a::new [a::b 1 2 3] (b::init [a::b])    

# no call to `a::b()` but otherwise the same:
\'a::b\'->new;          # a::new [a::b] (b::init [a::b])
\'a::b\'->new(1,3); # a::new [a::b 1 2 3] (b::init [a::b])

new a::b::;           # a::new [a::b] (b::init [a::b])
new a::b:: 1,3;   # a::new [a::b 1 2 3] (b::init [a::b])
有趣的是,到目前为止唯一不同的是以下两行成为语法错误:
new a::b;
new a::b 1,3;
出于相同的原因,这也是语法错误,因为“ 8”是1。 如果定义了“ 9”子例程,则将其解析为“ 10”,这对于两个相邻的裸字子例程是正常的。 就个人而言,我认为
new a::b
会成为语法错误,而明确的版本
new a::b::
始终可以正常工作,因为下面的tchrist会有所帮助。     

解决方法

这就是为什么
$thingie = new Some::Class one => 1,two => 2;
要么
$thingie = new Some::Class::
               one => 1,two => 2,;
存在,因此只需使用它。 但是,是的,我想您会遇到很多麻烦,因为我是世界上唯一一个愿意打包报价的人。我现在没有时间深入研究旧的问题测试代码,但是我敢肯定,如果您所说的话,这最终会使您哭泣。     ,“我有兴趣知道我没有想到过的这项技术是否存在任何隐患。” 我认为隐藏的陷阱是与大多数OOP lang定义构造函数的方式缺乏一致性。显然,Perl喜欢它的TMTOWTDI理念,但是如果您以后不在/不在的情况下不得不维护您的代码,则可能需要更多的时间来了解您的代码在做什么。 另外,如果要添加另一个构造函数怎么办?我已经看到了一些类,其中的构造函数名为:new,new_from_file等。也许不是最好的设计,但它确实说明了对象是以独特的方式构造的。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...