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

Есть ли разница между "стандартным" и объявлением пакета?

Обычно пакет запускается просто как

package Cat;
... #content
!0;

Я только что обнаружил, что начиная с perl 5.14 также существует синтаксис "block".

package Cat {
    ... #content
}

Возможно, это одно и то же. Но, чтобы быть уверенным, существует ли какая-либо разница?

И о 1; в конце файла пакета. Возвращаемое значение любого блока принимается за значение последнего оцененного выражения. Могу ли я поставить 1; до закрытия }? Чтобы сделать require счастливым, есть ли разница между:

package Cat {
    ... #content
    1; 
}

и

package Cat {
    ... #content 
}
1;
4b9b3361

Ответ 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; ... }

Мне бы это понравилось, но это предложение не было принято.


requiredo) требует, чтобы последнее выражение, оцениваемое в файле, возвращало истинное значение. { ... } оценивает последнее значение, оцениваемое внутри, так что это нормально:

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; прежняя форма вернется к более старым версиям. Более аккуратная форма была добавлена ​​в основном для визуальной аккуратности; у него нет никакой смысловой разницы, о которой стоит беспокоиться.