Есть ли вред в Perl при создании подпрограммы с тем же именем, что и у пакета? - PullRequest
10 голосов
/ 25 мая 2011

Скажем, у меня есть пакет с именем 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, 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:: будетВсегда работаю, * * * * * * * * * * * * * * * * * * * * * * * * 1036

Ответы [ 2 ]

7 голосов
/ 25 мая 2011

Это точно , почему существует

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

или

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

, так что просто используйте это.

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

4 голосов
/ 25 мая 2011

«Мне интересно знать, есть ли какие-либо скрытые ошибки в этой технике, о которых я не задумывался».

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...