Когда это в порядке для использования неопределенной переменной в жемчуге с включенными предупреждениями?

С включенными предупреждениями жемчуг обычно печатает Use of uninitialized value $foo если $foo используется в выражении и не был присвоен значение, но в некоторых случаях оно в порядке, и переменную рассматривают как ложь, 0, или '' без предупреждения.

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

15
задан Evan Carroll 31 January 2010 в 17:28
поделиться

4 ответа

Резюме

  • Логические тесты
  • Увеличение или уменьшение неопределенного значения
  • Добавление к неопределенному значению
  • Автовивификация
  • Другие мутаторы

Логические тесты

Согласно документации perlsyn ,

Число 0 , строки '0' и '' , пустой список () и undef - все они ложны в логическом контексте. Все остальные значения верны.

Поскольку неопределенное значение ложно, следующая программа

#! /usr/bin/perl

use warnings;

my $var;
print "A\n" if $var;
$var && print "B\n";
$var and print "C\n";
print "D\n" if !$var;
print "E\n" if not $var;
$var or print "F\n";
$var || print "G\n";

выводит с D по G без предупреждений.

Увеличение или уменьшение неопределенного значения

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

#! /usr/bin/perl

use warnings;

my $i;
++$i while "aaba" =~ /a/g;
print $i, "\n";

Приведенный выше код выводит 3 без предупреждения.

Добавление к неопределенному значению

Подобно неявному нулю, нет необходимости явно инициализировать скаляры для пустой строки, если вы добавите к ней хотя бы один раз:

#! /usr/bin/perl

use warnings;
use strict;

my $str;
for (<*>) {
  $str .= substr $_, 0, 1;
}
print $str, "\n";

Autovivification

Один пример: " автовивификация."Из статьи в Википедии :

Автовивификация - отличительная особенность языка программирования Perl, включающая динамическое создание структур данных. Автовивификация - это автоматическое создание ссылки на переменную при разыменовании неопределенного значения. Другими словами, автовивификация Perl позволяет программисту обращаться к структурированной переменной и произвольным подэлементам этой структурированной переменной без явного предварительного объявления существования переменной и ее полной структуры.

Например:

#! /usr/bin/perl

use warnings;

my %foo;
++$foo{bar}{baz}{quux};

use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;

Даже если мы не инициализируем явно промежуточные ключи, Perl позаботится о каркасе:

$VAR1 = {
  'bar' => {
    'baz' => {
      'quux' => '1'
    }
  }
};

Без автовивификации код потребовал бы большего количества шаблонов:

my %foo;
$foo{bar} = {};
$foo{bar}{baz} = {};
++$foo{bar}{baz}{quux};  # finally!

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

#! /usr/bin/perl

use warnings;

my %foo;
print $foo{bar}{baz}{quux}, "\n";
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;

получаем

Use of uninitialized value in print at ./prog.pl line 6.

$VAR1 = {
  'bar' => {
    'baz' => {}
  }
};

Обратите внимание, что промежуточные ключи автоматически оживились.

Другие примеры автовивификации:

  • ссылка на массив

     my $ a; 
    push @ $ a => "foo"; 
     
  • ссылка на скаляр

     my $ s; 
     ++ $$ s; 
     
  • ссылка на хэш

     my $ h; 
     $ h-> {foo} = "bar"; 
     

К сожалению, Perl (пока!) не автовивифицирует следующее:

my $code;
$code->("Do what I need please!");

Другие мутаторы

В ответе на аналогичный вопрос ysth сообщает

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

Это: ++ и - (до или после), + = , - = , .= , | = , ^ = , && = , || = .

Будучи «определенным-или», // = успешно изменяет неопределенное значение без предупреждения.

18
ответ дан 1 December 2019 в 03:24
поделиться

Если вы ищете примеры о том, как разработать приложение, посмотрите на многие рамки - это хороший запуск. Даже только их структура файлов даст вам идею. Как правило, они организуют свой код в модули, где также проживают как HTML-шаблоны HTML. Ни один, в частности, лучше посмотреть, но попробуйте: CakePhp, Symfony, Codeigniter или Agavi.

Они не будут делать отличную работу по предложению того, как организовать файлы JavaScript и CSS. Когда я делаю приложение, у меня обычно есть только горсть файлов CSS. Я удивлен, что вам, кажется, нужно понадобиться на странице, но если вы сделаете: встраивать их. Преимущество листов внешних стилей полностью потеряно, если нет ничего многоразового использования о своем стиле. Файлы JavaScript, опять же, если они не используются, вы должны просто встраивать их. Менее HTTP-запросы на нагрузку на страницу делает всех счастливыми.

Когда вы оказываете себя чистящим для определенного файла, который упрямо не поставит себя, GREP - это бесценный инструмент. Вот случайная статья , которая иллюстрирует свое использование.

-121--3375312-

всегда Удачные предупреждения Даже Pesky Anoying.

Неопределенные предупреждения могут быть выключены. Вы можете сделать это, создавая новый объем для операции. См. Perldoc Perllexwarn для получения дополнительной информации. Этот метод работает во всех версиях Perl.

{
  no warnings 'uninitialized';
  my $foo = "foo" + undef = "bar";
}

Для многих двоичных операторов вы можете использовать новый материал Perl 5.10, ~~ и // ; См. Perldoc Perlop для получения дополнительной информации.

use warnings;
my $foo = undef;
my $bar = $foo // ''; ## same as $bar = defined $foo ? $foo : ''

также является вариантом // = // = // = // = , который устанавливает переменную, если она не определена:

$foo //= '';

Умный сопоставление ( ~~ ) Оператор довольно крутая, и позволяет смарт Сравнения, это вид нефте, проверьте это в Perldoc perlsyn :

use warnings;
my $foo = "string";
say $foo eq undef;  # triggers warnings
say $foo ~~ undef;  # no undef warnings
2
ответ дан 1 December 2019 в 03:24
поделиться

Реальный ответ должен быть: почему вы хотите включить это предупреждение? undef - это совершенно хорошее соотношение для переменной (как любой, кто когда-либо работал с базой данных, может сказать вам), и это часто имеет смысл дифференцироваться между True (что-то случилось), false (ничего не произошло) и undef (ошибка произошла).

, а не поговорка

use strict;
use warnings;

, скажем

use common::sense;

, и вы получите все преимущества предупреждений, но с раздражающими, как неопределенные переменные.

Common :: Sense доступен от CPAN.

0
ответ дан 1 December 2019 в 03:24
поделиться

Пока что найденные мной дела..:

  • autovivification (gbacon's answer)
  • boolean context, например if $foo или $foo || $bar
  • с ++ или --
  • слева от +=, -=, или . =

-=

.
2
ответ дан 1 December 2019 в 03:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: