Есть ли разница между "стандартным" и объявлением пакета?
Обычно пакет запускается просто как
package Cat;
... #content
!0;
Я только что обнаружил, что начиная с perl 5.14 также существует синтаксис "block".
package Cat {
... #content
}
Возможно, это одно и то же. Но, чтобы быть уверенным, существует ли какая-либо разница?
И о 1;
в конце файла пакета. Возвращаемое значение любого блока принимается за значение последнего оцененного выражения. Могу ли я поставить 1;
до закрытия }
? Чтобы сделать require
счастливым, есть ли разница между:
package Cat {
... #content
1;
}
и
package Cat {
... #content
}
1;
Ответы
Ответ 1
Конечно, есть разница. Второй вариант имеет блок.
Объявление A package
устанавливает текущее пространство имен для подмножеств и глобальных переменных. Обычно это область видимости, то есть область действия заканчивается концом строки файла или eval или с закрывающим блоком.
Синтаксис package NAME BLOCK
- это просто синтаксический сахар для
{ package NAME;
...;
}
и даже сводится к тем же кодам операций.
Хотя объявление package
синтаксически является выражением, это не семантически верно; он просто устанавливает свойства времени компиляции. Поэтому последний оператор последнего блока - это последний оператор файла, и нет никакой разницы между
package Foo;
1;
и
package Foo {
1;
}
WRT. последнее утверждение.
Синтаксис package BLOCK
интересен главным образом потому, что он похож на class Foo {}
на других языках, я думаю. Поскольку блок ограничивает область видимости, это также облегчает использование переменных с использованием более узких областей. Подумайте:
package Foo;
our $x = 1;
package main;
$::x = 42;
say $x;
Вывод: 1
, потому что our
лексически охвачен как my
и просто объявляет псевдоним! Это может быть предотвращено синтаксисом блока:
package Foo {
our $x = 1;
}
package main {
$::x = 42;
say $x;
}
работает как ожидалось (42
), хотя strict
не доволен.
Ответ 2
package Foo { ... }
эквивалентно
{ package Foo; ... }
который отличается от следующего в том, что он создает блок
package Foo; ...
Это имеет значение только в том случае, если в файле содержится следующий код.
package Foo { ... }
не эквивалентно
BEGIN { package Foo; ... }
Мне бы это понравилось, но это предложение не было принято.
require
(и do
) требует, чтобы последнее выражение, оцениваемое в файле, возвращало истинное значение. { ... }
оценивает последнее значение, оцениваемое внутри, так что это нормально:
package Foo { ...; 1 }
Размещение 1;
снаружи имеет больше смысла для меня; он относится к файлу, а не к пакету — но это просто выбор стиля.
Ответ 3
Есть разница. Если вы можете попробовать запустить ниже двух разных фрагментов кода (просто импортируйте модули в файл perl)
# perlscript.pl
use wblock;
wblock::wbmethod();
Первый фрагмент кода без блока, wblock.pm
package wblock1;
my $a =10;
sub wbmethod1{
print "in wb $a";
}
package wblock;
sub wbmethod{
print "in wb1 $a";
}
1;
Второй с wblock.pm
package wblock1 {
my $a =10;
sub wbmethod1{
print "in wb $a";
}
1;
}
package wblock {
sub wbmethod{
print "in wb1 $a";
}
1;
}
Теперь разница, как вы могли видеть, переменная $a
недоступна для пакета wblock
, когда мы используем BLOCK. Но без BLOCK мы можем использовать $a
из другого пакета, так как он предназначен для файла.
Подробнее сказать perldoc:
То есть, формы без БЛОКА действуют в конце текущую область действия, так же как мое, состояние и наши операторы.
Ответ 4
Есть разница, но только если вы выполняете жесткое программирование. Специально, если вы используете переменную my
для пакетов. Соглашение для Perl состоит в том, чтобы иметь только один пакет для каждого файла и весь пакет в одном файле.
Ответ 5
Есть еще одно отличие, которое другие ответы не дали, что может помочь объяснить, почему есть два.
package Foo;
sub bar { ... }
всегда был способ сделать это в Perl 5. Синтаксис package BLOCK
package Foo {
sub bar { ... }
}
был добавлен только в perl 5.14.
Основное различие заключается в том, что последняя форма более аккуратная, но работает только с 5.14; прежняя форма вернется к более старым версиям. Более аккуратная форма была добавлена в основном для визуальной аккуратности; у него нет никакой смысловой разницы, о которой стоит беспокоиться.