Perl Scope Путаница с форматом / записью - PullRequest
0 голосов
/ 02 января 2019

Почему $var недоступно (выходит за рамки?) До write при объявлении с my, если его область действия в значительной степени на уровне пакета?

package ASDF;
use warnings;
use strict;
use feature 'say';

my $var = 'foo';

format =
@<<<<< @>>>>>
'test : ', $var
.


sub test {
    say $var;
    write;
}


1;

Вызывается с:

perl -wE 'use ASDF; ASDF::test();'

Производит:

foo
Variable "$var" is not available at ASDF.pm line 16.
Use of uninitialized value $var in formline at ASDF.pm line 10.
test :

По-видимому, он доступен для say в том же объеме ...

Замена my на our исправляет это:

foo
test :    foo

Почему write не может правильно поднять $var?
Это проблема с областью действия или проблема с реализацией Perl write или format?

1 Ответ

0 голосов
/ 30 января 2019

Внизу документации формата Perl написано:

Лексические переменные (объявленные с "my") не видны в формате, если формат не объявлен в рамках лексической переменной.

Чтение, которое подразумевает, что то, что вы пытаетесь, будет работать, но очевидно, что переменные с лексической областью работают по-разному для format и write при вызове извне пакета, в котором они были объявлены. Кроме того, все примеры в статья использовать глобальные переменные ...

В этом более современном руководстве по формату повторяется, что вы можете столкнуться с проблемами, если будете использовать переменные с лексической областью (переменные, объявленные с my), потому что write выбирает переменные из текущего пакета и, как указано в комментарии вашего вопроса были написаны в то время, когда в Perl не было ключевого слова my или лексической области видимости.

Решения, предлагаемые в статье:

Когда вы готовы вывести некоторые данные, вы используете запись. Этот дизайн показывает возраст форматов, так как write не принимает аргументов для заполнения изображений. Он использует переменные, которые находятся в области видимости.

our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();

Форматы также немного хитры, потому что вы не передаете аргументы для записи, чтобы заполнить картинки. Perl полагается на переменные с указанными именами, находящимися в области видимости. Вы можете использовать лексические переменные, но они должны быть в той же области видимости, что и определение формата, и они должны находиться в области видимости, когда вы вызываете write. Это нецелесообразно делать с лексическими выражениями, поэтому самый гибкий способ - использование локализованных переменных пакета:

foreach my $record ( @cats ) {
    local( $id, $name, $food ) = @$record;
    write( $fh );
}

А также этот совет в заключение:

  • Используйте локализованные переменные пакета, чтобы установить данные для формата

Таким образом, our и local, похоже, являются подходящим вариантом, если вы хотите продолжать использовать format и write в современном Perl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...