2010-11-03 2 views
7

Perl automatically initializes variables по умолчанию undef.Как я могу автоматически инициализировать все скалярные переменные в Perl?

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

+0

Инициализация переменных 'undef' по-прежнему является инициализацией. – zigdon

+7

Могу я спросить _why_ вы бы хотели сделать это? – Zaid

+0

@ Zaid: Полная история. Я читаю Code Complete (в которой упоминается всегда инициализация переменных во время объявления, если это возможно) и смотрел на один из моих старых файлов, в котором используется множество счетчиков, которые я инициализировал сначала «zero» но позже удалили все ненужные инициализации. Я думаю о повторном вводе всех инициализаций и задал этот вопрос, чтобы найти лучший способ сделать это. – Lazer

ответ

12

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

int f(void) { 
    int counter; 
} 

значение counter является то, что происходит, чтобы занять эту память.

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

my $counter; 

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

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

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

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

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

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

+2

+1 для unasking с изящным объяснением – daxim

+2

Когда это было * переписано * превращено в * refactored *, во всяком случае? ☺ – tchrist

5

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

В 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

11

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

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

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

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

sub zero {$_ = 0 for @_} 

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

или даже:

$_ = 0 for my ($x, $y, $z); 
+0

спасибо. Кстати, как '$ [' опасно? – Lazer

+1

Это индекс, из которого начинаются массивы. он должен был заставить perl вести себя как awk, установив его в 1. он устарел и предупреждает и имеет только область файла и должен быть установлен во время компиляции из-за всех ошибок, которые он может вызвать в несвязанном коде. perldoc perlvar для получения дополнительной информации –

+0

Не могу понять, почему вам нужно инициализировать что-то ноль в точке объявления. – tchrist

0

ли вы, есть конкретная причина для желания сделать это, или это просто "потому что Код Завершить te говорит, что я должен "?

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

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

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