2016-12-12 5 views
8

Я пытался use constant значений в Perl и наткнулся на следующее странное поведение:Где константы perl заменяются на их значения?

#!/usr/bin/perl 
use strict; 
use warnings; 

use Data::Dumper; 

use constant { 
    a => "b" 
}; 

my $c = { a => a }; 
my %d; 
$d{a} = a; 

print Dumper($c); 
print Dumper(\%d); 

Выведет

$VAR1 = { 
      'a' => 'b' 
     }; 
$VAR1 = { 
      'a' => 'b' 
     }; 

Константа a была заменена на правой стороне выражения $d{a} = a и a => a, но не с левой стороны.

Я знаю, что константы реализованы с использованием inlinable подлодки (documented here), и что имена суб оценить их имена, если они не предопределенное (documented here), но я не вижу причин, почему в моем примере a оценивает один раз до значения и один раз на имя в той же строке кода, особенно в присваивании хэша. a => a может быть следствием =>, переводящего левый сайт в виде строки, если он начинается с буквы.

Sidenote: Добавление круглых скобок, чтобы сделать суб-вызов явным дают ожидаемый результат:

# ... 
my $c = { a() => a }; # or my $c = { a, a }; 
my %d; 
$d{a()} = a; 
# .... 

Выход:

$VAR1 = { 
      'b' => 'b' 
     }; 
$VAR1 = { 
      'b' => 'b' 
     }; 

(все примеры протестирован с Perl 5.18)

+1

Честно говоря, я склонен найти модуль CONSTANT только больше проблем, чем он того стоит, и имеет тенденцию «просто» использовать верхний регистр с именем package vars. – Sobrique

+1

Я использую [Const :: Fast] (http://search.cpan.org/~leont/Const-Fast-0.014/lib/Const/Fast.pm) и не имел проблем. См. [Этот обзор] (http://neilb.org/reviews/constants.html) для выбора. Вот также недавняя статья [https://www.nu42.com/2016/05/perl-define-constants.html). – zdim

ответ

14

Концом страницы constant, по адресу CAVEATS, имеет ответ

У вас могут возникнуть проблемы, если вы используете константы в контексте, который автоматически цитирует открытые слова (как это верно для любого вызова подпрограммы). Например, вы не можете сказать $hash{CONSTANT}, потому что CONSTANT будет интерпретироваться как строка.

Затем происходит с раствором вы нашли

Использования $hash{CONSTANT()} или $hash{+CONSTANT} для предотвращения bareword квотирования механизма с ног в.

Тогда заклинания это для хэш, а

Аналогичным образом, поскольку оператор => приводит к немедленному выходу из левого края, вы должны сказать CONSTANT() => 'value' (или просто использовать запятую вместо большой стрелки) вместо CONSTANT => 'value'.

+3

Поздравляем с достижением 10k. –

+0

Urg. Они действительно разобрались, написав это на весь верх страницы. Благодарю. – urzeit

+2

@JonathanLeffler О, спасибо :) Идти с нуля и узнав, как это сделать, было ... опытом. – zdim

Смежные вопросы