В 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, но мне интересно узнать, есть ли какие-либо скрытые ошибки в этой технике, о которых я не думал.


Update:

Наследование работает правильно, как показано на примере здесь:

{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, 2, 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, 2, 3;   # a::new [a::b 1 2 3] (b::init [a::b])

Интересно, что единственное, что пока отличается от того, что следующие 2 строки становятся синтаксическими ошибками:

new a::b;
new a::b 1, 2, 3;

Которая является синтаксической ошибкой по той же причине some_undefined_sub some_defined_sub; является одной.

Если определена подпрограмма new, она анализируется как new( a::b(...) ), которая является нормальной для двух соседних подпрограмм с открытым словом.

Лично я согласен с тем, что new a::b становится синтаксической ошибкой, однозначная версия new a::b:: всегда будет работать, как показывает tchrist ниже.

Ответ 1

Thats точно, почему

$thingie = new Some::Class one => 1, two => 2;

или

$thingie = new Some::Class::
               one => 1,
               two => 2,
           ;

существует, поэтому просто используйте это.

Но да, я думаю, вы попадете в целую кучу неприятностей, так как я единственный человек в мире, который беспокоится о пакете-цитате. У меня нет времени прямо сейчас, чтобы прокопать мой старый код для тестирования проблем, но я уверен, что это в конечном итоге заставит вас плакать, если вы пойдете по дороге, о которой вы говорите.

Ответ 2

"Мне интересно узнать, есть ли какие-то скрытые причины для этой техники, о которых я не думал".

Я думаю, что скрытая причина - отсутствие согласованности с тем, как большинство OOP-языков определяют конструкторы. Очевидно, Perl нравится его философия TMTOWTDI, но кто-то, кто должен поддерживать ваш код позже, когда/если вас нет, может занять больше времени, чтобы понять, что делает ваш код.

Кроме того, что, если вы хотите добавить другой конструктор? Я видел некоторые классы, где есть конструкторы с именем: new, new_from_file и т.д. Возможно, это не лучший дизайн, но он прояснил, что объект был создан уникальным образом.