Могу ли я объявить глобальные переменные в подпрограмме в perl? - PullRequest
0 голосов
/ 21 февраля 2019

Могу ли я объявить глобальные переменные в подпрограмме на perl с use strict?

Рассмотрим следующий код:

#!/usr/bin/perl
# $Id: foo,v 1.5 2019/02/21 10:41:08 bennett Exp bennett $

use strict;
use warnings;

initialize();

print "$lorem\n";

exit 0;

sub initialize {
    # How would one delcare "$lorem" here such that it is available as
    # a global?

    $lorem = <<_EOM_
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
_EOM_
    ;
}

Обратите внимание, что я не спрашиваю, использует ли (ab) глобальные переменныев этом смысле хорошая идея;Я уверен, что это не так.

Я пробовал несколько комбинаций our и $main::, но все они терпят неудачу так, как вы ожидаете.

На данный момент мне просто любопытно.Это можно сделать?Интересно, будут ли работать какие-то махинации с блоком BEGIN.

Сработает следующее, но, как указывает @simbabque, это ужасно:

#!/usr/bin/perl
# $Id: foo,v 1.7 2019/02/21 19:48:26 bennett Exp bennett $

use strict;
use warnings;

initialize();

printf("$main::lorem\n");

exit 0;

sub initialize {
    # How would one delcare "$lorem" here such that is is available as
    # a global-ish?

    our $lorem = <<_EOM_
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
_EOM_
    ;
}

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Я верю, что ответ "нет".Не с use strict.В число функций use strict входит проверка того, используете ли вы переменную перед ее объявлением.

Понятие о желании сделать это, как я делал выше, противоречит проверкам времени компиляциииз use strict.

Спасибо @simbabque за то, что помогли мне обдумать это более четко.

Вместо того, чтобы удалить use strict, я собираюсь переместить безобразие огромного $lorem тип переменных (и их много) в отдельный пакет.

-E

0 голосов
/ 21 февраля 2019

Для вашего конкретного примера вам не нужна переменная global .

Perl имеет переменных пакета .Они создаются с помощью our, и к ним также можно получить доступ с помощью $namespace:: (где main - пространство имен по умолчанию, и $:: также подходит для этого).Это global , но мы редко называем их так.

Вы должны иметь в виду, что our создает лексический псевдоним, поэтому, если вы объявите его внутриподпрограмма, она не будет доступна снаружи, потому что в этой большей области нет лексического псевдонима.

use strict;

sub foo {
    our $bar = 123;
}

foo();
print $bar; # error

Вам необходимо объявить переменную в большей области.

use strict;

our $bar;

sub foo {
    $bar = 123;
}

foo();
print $bar;

Это будет работать, потому что $bar теперь доступно в области видимости файла.

Все это применимо только при включенном use strict.Если вы не объявите переменную, она автоматически станет переменной пакета.Однако, если вы включите строгий, вы должны объявить все переменные.Поэтому вам нужно быть явным.

Вы также можете использовать my, если вы объявите это вне подпрограммы.

use strict;

my $bar;

sub foo {
    $bar = 123;
}

foo();
print $bar;

Поскольку вы делаете это в сценарии, и нет явного объявления пакета, я думаю, можно с уверенностью предположить, что другие модули не задействованы.В этом случае не имеет значения, используете ли вы my или our.

Если вы используете это в пакете с другими файлами, это будет иметь значение.Переменные, объявленные в области видимости файла с my, имеют вид private , поскольку нет прямого доступа к ним извне.

package Foo;
use strict;

my $bar = 123;

### other file
use Foo;

# no way to get $bar as there is no $Foo::bar

Но если вы используете our(или устаревший use vars) станет переменной пакета.

package Foo;
use strict;

our $bar = 123;

### other file

use Foo;
print $Foo::bar;

Можно ли объявить глобальные переменные в подпрограмме в Perl?

Да , вы можете объявить переменные пакета в подпрограмме с помощью our.Но вы не можете получить к ним доступ как к лексическим переменным вне области, в которой они были объявлены, поэтому вам нужно получить к ним доступ с помощью их полного имени пакета, и это ужасно.

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