Подтвердить что ты не робот

В чем разница между новыми Some:: Class и Some:: Class-> new() в Perl?

Много лет назад я помню другого программиста, который консультировал это:

new Some::Class;    # bad! (but why?)

Some::Class->new(); # good!

К сожалению, теперь я не могу вспомнить причину.:( Обе формы будут работать корректно, даже если конструктор фактически не существует в модуле Some:: Class, но вместо этого наследуется от родителя где-то.

Ни одна из этих форм не такая же, как Some:: Class:: new(), которая не передаст имя класса в качестве первого параметра для конструктора, поэтому эта форма всегда неверна.

Даже если эти две формы эквивалентны, я нахожу Some:: Class- > new() более понятным, так как это следует стандартным соглашениям о вызове метода в модуле, а в perl - "новом", метод не является специальным - конструктор можно назвать чем угодно, а new() мог бы что-либо сделать (хотя, конечно, мы обычно ожидаем, что он будет конструктором).

4b9b3361

Ответ 1

Использование new Some::Class называется "косвенным" вызовом метода, и это плохо, потому что оно вводит некоторую двусмысленность в синтаксис.

Одна из причин, по которой он может потерпеть неудачу, заключается в том, что у вас есть массив или хэш объектов. Вы можете ожидать

dosomethingwith $hashref->{obj}

чтобы быть равным

$hashref->{obj}->dosomethingwith();

но он фактически анализирует как:

$hashref->dosomethingwith->{obj}

который, вероятно, не тот, который вам нужен.

Другая проблема заключается в том, что в вашем пакете есть функция с тем же именем, что и метод, который вы пытаетесь вызвать. Например, что, если какой-то модуль, который вы use 'd экспортировали функцию с именем dosomethingwith? В этом случае dosomethingwith $object является неоднозначным и может приводить к загадочным ошибкам.

Использование синтаксиса -> исключительно устраняет эти проблемы, поскольку метод и то, что вы хотите, чтобы метод работал, всегда ясны компилятору.

Ответ 2

См. Синтаксис косвенных объектов в документации perlobj для объяснения ее ошибок. freido answer охватывает один из них (хотя я стараюсь избегать этого с явным parens вокруг моих вызовов функций).

Ларри однажды пошутил, что он должен был сделать С++ счастливым о new, и, хотя люди скажут вам, что никогда не будут использовать его, вы, вероятно, все это делаете. Рассмотрим это:

print FH "Some message";

Вы когда-нибудь задумывались о том, что после дескриптора файла не было запятой? И нет никакой запятой после названия класса в косвенной объектной нотации? Что здесь происходит. Вы можете переписать это как вызов метода при печати:

FH->print( "Some message" );

Возможно, вы испытали какую-то странность в print, если вы сделали это неправильно. Помещение запятой после явного дескриптора файла превращает его в аргумент:

print FH, "some message";     # GLOB(0xDEADBEEF)some message

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

Ответ 3

Синтаксис косвенного объекта неодобрен по причинам, но это не имеет ничего общего с конструкторами. У вас почти никогда не будет функции new() в вызывающем пакете. Скорее, вы должны использовать Package- > new() для двух других (лучше?) Причин:

  • Как вы сказали, все другие методы класса принимают форму Package- > method(), поэтому согласованность - это хорошая вещь

  • Если вы передаете аргументы конструктору или вы берете результат конструктора и сразу вызываете его методы (если, например, вы не заботитесь о сохранении объекта), это проще например,

$foo = Foo->new(type => 'bar', style => 'baz');
Bar->new->do_stuff;

чем

$foo = new Foo(type => 'bar', style => 'baz');
(new Bar)->do_stuff;

Ответ 4

Другая проблема заключается в том, что new Some::Class происходит во время выполнения. Если есть ошибка, и вы не проверяете ветки на это утверждение, вы никогда не узнаете об этом до тех пор, пока это не произойдет в процессе производства. Лучше использовать Some::Class->new, если вы не выполняете динамическую программирование.