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

Является ли использование строгим с пустым списком, эквивалентным тому, что он не используется строго?

TL;DR: см. заголовок вопроса.

В оригинальной версии вопроса в верхней части программы было use strict ();. Никакие переменные не были объявлены с помощью my. Программа работала. Я указал, что код не будет работать из-за отсутствия my s, но оказывается, что я ошибся.

$ perl e 'use strict (); $foo = 1'

Эта программа работает. Это не сбой. Но, очевидно, это сбой:

$ perl -e 'use strict; $foo = 1'
Global symbol "$foo" requires explicit package name (did you forget to declare "my $foo"?) at -e line 1.
Execution of -e aborted due to compilation errors.

Моя первая идея состояла в том, чтобы отстранить ее, чтобы увидеть, происходит ли что-то еще.

$ perl -MO=Deparse -e 'use strict (); $foo = 1'
use strict ();
$foo = 1;
-e syntax OK

Но это не так. Затем он заставлял меня думать, вы можете сделать use strict 'vars', который только активирует vars вещь 1. Это, очевидно, делает это, вызывая import.

use strict совпадает с BEGIN { require strict; strict->import; }, поэтому те же правила, что и для модулей, должны применяться и к прагматам. Если я делаю use Foo (), ничего не импортируется. Следовательно, use strict (); должен быть таким же, как require strict;, только во время выполнения, потому что ничего не импортируется.

$ perl -e 'require strict; $foo = 1'

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

Так что же это на самом деле? Когда Perl достигает моего фактического кода, он, вероятно, уже столкнулся с прагмой strict где-то в другом месте, поэтому он не будет загружать его снова. И он ничего не импортирует.

$ perl -e 'print %INC'

К сожалению. Это ничего не печатает. %INC пусто. Но если мы используем другой модуль, в нем есть что-то.

$ perl -MData::Dumper -e 'print Dumper \%INC'
$VAR1 = {
          'warnings.pm' => '/usr/share/perl/5.22/warnings.pm',
          'overload.pm' => '/usr/share/perl/5.22/overload.pm',
          'Carp.pm' => '/usr/share/perl/5.22/Carp.pm',
          'strict.pm' => '/usr/share/perl/5.22/strict.pm',
          'overloading.pm' => '/usr/share/perl/5.22/overloading.pm',
          'constant.pm' => '/usr/share/perl/5.22/constant.pm',
          'bytes.pm' => '/usr/share/perl/5.22/bytes.pm',
          'Data/Dumper.pm' => '/usr/lib/x86_64-linux-gnu/perl/5.22/Data/Dumper.pm',
          'XSLoader.pm' => '/usr/share/perl/5.22/XSLoader.pm',
          'Exporter.pm' => '/usr/share/perl/5.22/Exporter.pm',
          'warnings/register.pm' => '/usr/share/perl/5.22/warnings/register.pm'
        };

Если мы загрузим Data:: Dumper, в какой-то момент был загружен strict. Но не в чистом -e примере.

$ perl -e 'use strict (); print %INC'
strict.pm/usr/share/perl/5.22/strict.pm

Ok. Это загружает strict.pm.

$ perl -e 'require strict; print %INC'
strict.pm/usr/share/perl/5.22/strict.pm

Так и получается. Но тем не менее, ни одна из strict не включена.

Итак, на самом деле вопрос: use strict () эквивалентен просто отсутствию оператора use strict вообще или что-то еще происходит?


1) perldoc strict относится к трем различным аргументам strict может принимать как вещи

4b9b3361

Ответ 1

use strict ();

(по существу) ничего не делает: см. документы:

Если вы не хотите вызывать метод импорта пакета (например, чтобы ваше пространство имен не изменялось), явно укажите пустой список:

use Module ();

Это точно эквивалентно

BEGIN { require Module }

Конечно, strict делает только что-то, если вы вызываете его метод import (который вы можете легко проверить, прочитав его исходный код, длина которого составляет всего около 150 строк). Таким образом, обход метода import обходит весь эффект use strict.