Что в этом плохого?
Проблем с нотацией косвенного метода можно избежать, но гораздо проще сказать людям, чтобы они избегали нотации косвенного метода.
Основная проблема в том, что очень легко случайно вызвать не ту функцию. Возьмем, например, следующий код:
package Widget;
sub new { ... }
sub foo { ... }
sub bar { ... }
sub method {
...;
my $o = new SubWidget;
...;
}
1;
Ожидается, что в этом коде new SubWidget
будет означать
SubWidget->new()
Вместо этого на самом деле это означает
new("SubWidget")
Тем не менее, использование strict перехватит большинство этих случаев этой ошибки. Если бы use strict;
был добавлен в приведенный выше фрагмент, возникла бы следующая ошибка:
Bareword "SubWidget" not allowed while "strict subs" in use at Widget.pm line 11.
Тем не менее, есть случаи, когда использование strict не обнаружит ошибку. В основном они включают использование скобок вокруг аргументов вызова метода (например, new SubWidget($x)
).
Значит, это значит
- Использование косвенной объектной нотации без скобок может привести к появлению странных сообщений об ошибках.
- Использование косвенной объектной нотации с скобками может привести к вызову неправильного кода.
Первое можно терпеть, а второго можно избежать. Но вместо того, чтобы говорить людям «избегайте использования скобок вокруг аргументов вызовов методов с использованием нотации косвенного метода», мы просто говорим людям «избегайте использования нотации косвенного метода». Он слишком хрупкий.
Есть еще одна проблема. Проблема не только в использовании косвенной объектной нотации, но и в ее поддержке в Perl. Наличие функции вызывает множество проблем. В первую очередь,
- Это вызывает некоторые синтаксические ошибки, приводящие к очень странным / вводящим в заблуждение сообщениям об ошибках, потому что код, похоже, использует ION, когда это не так.
- Это предотвращает реализацию полезных функций, поскольку они противоречат допустимому синтаксису ION.
С другой стороны, использование no indirect;
помогает решить первую проблему.
Как следует переписать эту строку?
Правильный способ написать вызов метода следующий:
my $some_object = Some::Module->new(FIELD => 'value');
Тем не менее, даже этот синтаксис неоднозначен. Сначала он проверит, существует ли функция с именем Some::Module
. Но это настолько маловероятно, что очень немногие люди защищаются от подобных проблем. Если вы хотите защитить себя, вы можете использовать следующее:
my $some_object = Some::Module::->new(FIELD => 'value');
person
ikegami
schedule
05.10.2015