Есть ли какой-нибудь способ сделать переменные типа $ a и $ b относительно строгих? - PullRequest
5 голосов
/ 30 сентября 2008

В свете комментария Майкла Кармана я решил переписать вопрос. Обратите внимание, что перед этим редактированием появляются 11 комментариев, и они подтверждают наблюдение Майкла о том, что я не написал вопрос таким образом, чтобы было понятно, о чем я спрашиваю. <Ч /> Вопрос: Каков стандартный - или самый чистый способ - подделать особый статус, который $a и $b имеют в отношении строгого, путем простого импорта модуля?

Прежде всего, некоторые настройки. Следующие работы:

#!/bin/perl
use strict;
print "\$a=$a\n";
print "\$b=$b\n";

Если я добавлю еще одну строку:

print "\$c=$c\n";

Я получаю ошибку во время компиляции, что означает, что ни один из моих ослепительных кодов печати не запускается.

Если я закомментирую use strict;, все будет нормально. За пределами ограничений $a и $b в основном особенные, так как sort передает два значения для сравнения с этими именами.

my @reverse_order = sort { $b <=> $a } @unsorted;

Таким образом, основное функциональное различие относительно $a и $b - даже если Perl "знает их имена" - в том, что вам лучше знать это при сортировке или использовании некоторых из функции в List :: Util .

Только при использовании строгого * $a и $b становятся специальными переменными совершенно по-новому. Они являются единственными переменными, которые строгие значения будут передаваться без жалоб, что они не объявлены.

: Теперь мне нравится строгий режим, но мне кажется, что если TIMTOWTDI (существует более одного способа сделать это) - это правило № 1 в Perl, это не очень TIMTOWDI. Там написано, что $a и $b особенные и все. Если вы хотите использовать переменные, вам не нужно объявлять $a и $b ваши парни. Если вы хотите добавить три переменные, добавив $c, неожиданно появится совершенно другой способ сделать это.

Не важно, что при манипулировании хешами $k и $v может иметь больше смысла:

my %starts_upper_1_to_25 
    = skim { $k =~ m/^\p{IsUpper}/ && ( 1 <= $v && $v <= 25 ) } %my_hash
;`

Теперь я пользуюсь и люблю строгий. Но я просто хочу, чтобы $k и $v были видны skim для наиболее компактного синтаксиса. И я бы хотел, чтобы это было видно просто

use Hash::Helper qw<skim>;

Я не задаю этот вопрос, чтобы узнать, как его замаскировать. Мой «ответ» ниже должен дать вам знать, что я знаю достаточно Perl, чтобы быть опасным. Я спрашиваю, есть ли способ заставить строго принимать другие переменные, или каково решение cleanest . Ответ вполне может быть нет. Если это так, то это просто не похоже на TIMTOWTDI.

Ответы [ 13 ]

1 голос
/ 30 сентября 2008

$a и $b являются просто глобальными переменными. Вы можете добиться аналогичных эффектов, просто объявив $k и $v:

use strict;
our ($k, $v);

(В данном случае $k и $v - это не глобальные переменные, а псевдонимы с лексической областью для переменных пакета. Но если вы не пересекаете границы, это достаточно похоже.)

0 голосов
/ 02 октября 2008

Модули, предложенные для использования экспорта, на самом деле ничем не отличаются от use vars. Но use vars нужно будет делать в каждом пакете, который использует переменную $ a-like. И our() должно быть сделано в каждой внешней области.

Обратите внимание, что вы можете избежать использования $ a и $ b даже для сортировки, используя $$ - прототип sub:

sub lccmp($$) { lc($_[0]) cmp lc($_[1]) }
print join ' ', sort lccmp
   qw/I met this guy and he looked like he might have been a hat-check clerk/;

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

0 голосов
/ 30 сентября 2008

РЕДАКТИРОВАТЬ - это на самом деле неверно , см. Комментарии. Оставив это здесь, чтобы дать другим людям шанс учиться на моей ошибке:)


О, вы спрашиваете, есть ли способ для модуля объявить $ k и $ v в пространстве имен CALLER? Вы можете использовать Exporter для отправки ваших переменных вызывающей стороне:

use strict;

package Test; 
use Exporter;

my @ISA = qw/Exporter/; 
my $c = 3; 
my @EXPORT = qw/$c/; 

package main; 
print $c;
...