Как я могу автоматически инициализировать все скалярные переменные в Perl? - PullRequest
7 голосов
/ 03 ноября 2010

Perl автоматически инициализирует переменные до undef по умолчанию.

Есть ли способ переопределить это поведение по умолчанию и сказать интерпретатору Perl инициализировать переменные zero (или другим фиксированным значением)?

Ответы [ 4 ]

13 голосов
/ 03 ноября 2010

Рекомендация в Code Complete важна для таких языков, как C, потому что, когда у вас есть

int f(void) {
   int counter;
}

, значение counter - это то, что может занять эту память.

В PerlКогда вы объявляете переменную, используя

my $counter;

, нет сомнений, что значение $counter равно undef, а не случайному мусору.

Следовательно, мотивация за рекомендацией,т.е. чтобы все переменные начинались с известных значений, автоматически выполняются в Perl и нет необходимости что-либо делать.

То, что вы делаете со счетчиками, - это увеличивать или уменьшать их.Результат:

my $counter;
# ...
++ $counter;

хорошо определен в Perl.$counter будет содержать значение 1.

Наконец, я бы сказал, что в большинстве случаев счетчики не нужны в Perl и может потребоваться переписать код, широко использующий переменные счетчика.

11 голосов
/ 03 ноября 2010

Насколько я знаю, это невозможно (и не должно быть, это даже более опасно, чем $[).

Вы можете инициализировать свои переменные следующим образом, чтобы сократить шаблон:

my ($x, $y, $z) = (0) x 3;

или переместить инициализацию в функцию:

sub zero {$_ = 0 for @_}

zero my ($x, $y, $z);

или даже:

$_ = 0 for my ($x, $y, $z);
5 голосов
/ 03 ноября 2010

Нет.Это может привести к некоторым очень страшным и трудным для расшифровки ошибкам, так что в любом случае не стоит менять подобное поведение.

В Perl вы можете объявлять переменные в тот момент, когда они вам нужны для первоговремя, поэтому обычно нет необходимости сначала объявлять их (с инициализацией или без), а затем использовать их позже.Кроме того, такие операторы, как ++, будут работать с неопределенными значениями так же хорошо, как и с нулем, поэтому вам вообще не нужно инициализировать счетчики:

# this is perfectly legal:
my $counter;
while ($some_loop)
{
    $counter++;
}

Однако я могу вставить заглушку для Moose , упомянув, что вы можете добиться автоматической инициализации атрибутов в ваших классах Moose:

package MyClass;
use strict;
use warnings;
use Moose;

has some_string => (
    is => 'rw', isa => 'Str',
    default => 'initial value',
);

has some_number => (
    is => 'rw', isa => 'Int',
    default => 0,
);
__PACKAGE__->meta->make_immutable;
1;

package main;
my $object = MyClass->new;
print "string has value: ", $object->some_string, "\n";
print "number has value: ", $object->some_number, "\n";

печатает:

строка имеет значение: начальное значение
число имеетзначение: 0

0 голосов
/ 04 ноября 2010

У вас есть конкретная причина желать сделать это, или это просто "потому что Code Complete говорит, что я должен"?

Если первое, пожалуйста, расскажите причину, и мы можем должным образом обсудить пути Perly для достижения вашей реальной цели.

Если последнее, пожалуйста, помните, что Code Complete - это набор рекомендаций для программирования на C, а не на Perl. Perl не является C и имеет свой собственный набор сильных и слабых сторон, что также означает, что у него есть другой набор ... и я ненавижу использовать эту фразу ... лучшие практики. Рекомендации, подходящие для одного языка, не обязательно относятся к другому. «Всегда инициализируйте переменные (если это возможно), когда вы объявляете их» - разумная практика в C, но обычно в Perl нет необходимости.

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