Общие глюки для Perl? [закрытый]

Лучшая идея - пройти через учебник, который свяжет все это вместе - как на стороне клиента, так и на стороне сервера. Набор учебных пособий:

Я связал версию Xamarin.Android. Изучение кода, когда вы идете и понимаете, что происходит, поможет вашему расследованию. После того, как вы пройдете учебное пособие, документы HOWTO на клиенте и сервере помогут вам в некоторых дополнительных вопросах, которые вы можете сделать:

Важно отметить, что когда вы используете Easy Tables, код под Node.js / JavaScript - не ASP.NET (вы указали на ASP.NET HOWTO)

75
задан 23 revs, 8 users 36% 23 May 2017 в 00:31
поделиться

26 ответов

То, что одинарные кавычки могут использоваться для замены:: в идентификаторах.

Рассмотрите:

use strict;
print "$foo";        #-- Won't compile under use strict
print "$foo's fun!"; #-- Compiles just fine, refers to $foo::s

Продвижение к следующей проблеме:

use strict;
my $name = "John";
print "$name's name is '$name'";
# prints:
#  name is 'John'

рекомендуемый способ избежать этого состоит в том, чтобы использовать фигурные скобки вокруг Вашего имени переменной:

print "${name}'s name is '$name'";
# John's name is 'John'

И также к use warnings, так как это скажет Вам об использовании неопределенной переменной $name::s

38
ответ дан Adam Bellaire 6 November 2019 в 21:04
поделиться

имена переменной Орфографической ошибки ... Я когда-то потратил весь код поиска и устранения неисправностей во второй половине дня, который не вел себя правильно только для нахождения опечатки на имени переменной, которое не является ошибкой в Perl, а скорее объявлением новой переменной.

-1
ответ дан paxos1977 6 November 2019 в 21:04
поделиться

Добавление дополнительных круглых скобок никогда не могло изменять значение кода , правильно? Право?

my @x = ( "A"  x 5 );      # @x contains 1 element, "AAAAA"
my @y = (("A") x 5 );      # @y contains 5 elements: "A", "A", "A", "A", "A"

, О, правильно, это - Perl.

РЕДАКТИРОВАНИЕ: Просто в придачу, если x называется в скалярном контексте, то круглые скобки не имеют значения, в конце концов:

my $z = ( "A"  x 5 );      # $z contains "AAAAA"
my $w = (("A") x 5 );      # $w contains "AAAAA" too

Интуитивный.

4
ответ дан j_random_hacker 6 November 2019 в 21:04
поделиться

Если Вы будете достаточно глупы сделать так, то Perl позволит Вам объявлять несколько переменных с тем же именем:

my ($x, @x, %x);

, поскольку Perl использует символы для идентификации контекст , а не переменная тип , это почти гарантирует беспорядок, когда более поздний код будет использовать переменные, особенно если $x ссылка:

$x[0]
$x{key}
$x->[0]
$x->{key}
@x[0,1]
@x{'foo', 'bar'}
@$x[0,1]
@$x{'foo', 'bar'}
...
4
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

Вы не можете локализовать экспортируемые переменные, если Вы не экспортируете весь typeglob.

5
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

Сравнение строк с помощью == и != вместо eq и ne. Например:

$x = "abc";
if ($x == "abc") {
    # do something
}

Вместо:

$x = "abc";
if ($x eq "abc") {
    # do something
}
6
ответ дан 2 revs, 2 users 92% 6 November 2019 в 21:04
поделиться

ответ Graeme Perrow был хорош, но это становится еще лучше!

, Учитывая типичную функцию, которая возвращает хороший список в контексте списка, Вы могли бы хорошо спросить: Что это возвратит в скалярном контексте? ("Типичным" я имею в виду общий падеж, в котором не говорится в документации, и мы предполагаем, что это не использует никакой wantarray забавный бизнес. Возможно, это - функция, которую Вы записали сами.)

sub f { return ('a', 'b', 'c'); }
sub g { my @x = ('a', 'b', 'c'); return @x; }

my $x = f();           # $x is now 'c'
my $y = g();           # $y is now 3

контекст, функция призвана, распространен к return операторы в той функции.

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

6
ответ дан 3 revs, 2 users 93% 6 November 2019 в 21:04
поделиться

Используя /o модификатор с regex шаблоном, сохраненным в переменной.

m/$pattern/o

Определение /o является обещанием, которое $pattern не изменится. Perl достаточно умен, чтобы распознать, изменился ли он, и перекомпилируйте regex условно, таким образом, нет никакого серьезного основания использовать /o больше. Поочередно, можно использовать qr// (например, если Вы одержимы предотвращением проверки).

6
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

Какие значения Вы ожидали бы _ содержать в следующем сценарии?

sub foo { } 

# empty subroutine called in parameters

bar( foo(), "The second parameter." ) ;

я ожидал бы получать в панель :

undef, "The second parameter." 

, Но _ содержит только второй параметр, по крайней мере, при тестировании с жемчугом 5.88.

7
ответ дан 6 November 2019 в 21:04
поделиться

Этот глюк фиксируется в Perl 5.10 - если Вам повезло работать где-нибудь, у которого не аллергия на обновление вещей>:-(

, я говорю о Переменная, Это является Законно Нулевым. Вы знаете, тот, который вызывает неожиданные результаты в пунктах как:

unless ($x) { ... }
$x ||= do { ... };

Perl 5.10 имеет//= или определенный - или оператор.

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

8
ответ дан Peter Mortensen 6 November 2019 в 21:04
поделиться

Константы могут быть переопределены. Простой способ случайно переопределить константу состоит в том, чтобы определить константу как ссылку.

 use constant FOO => { bar => 1 };
 ...
 my $hash = FOO;
 ...
 $hash->{bar} = 2;

Теперь НЕЧТО является {панелью => 2};

при использовании mod_perl (по крайней мере, в 1,3) новое значение НЕЧТО сохранится, пока модуль не обновляется.

9
ответ дан cwhite 6 November 2019 в 21:04
поделиться
my $x = <>;
do { 
    next if $x !~ /TODO\s*[:-]/;
    ...
} while ( $x );

do не цикл. Вы не можете next. Это - инструкция выполнить блок. Это - то же самое как

$inc++ while <>;

, Несмотря на который это похоже на конструкцию в языковой семье C.

11
ответ дан Axeman 6 November 2019 в 21:04
поделиться

Я сделал это однажды:

my $object = new Some::Random::Class->new;

Взял меня возрасты для нахождения ошибки. Косвенный синтаксис метода eeevil.

12
ответ дан Dan 6 November 2019 в 21:04
поделиться

Путание ссылок и фактических объектов:

$a = [1,2,3,4];
print $a[0];

(Это должен быть один из $a->[0] (лучший), $a[0], @{$a}[0] или @$a[0])

15
ответ дан Christopher Bottoms 6 November 2019 в 21:04
поделиться

Использование неинициализированного значения в конкатенации...

Этот сводит меня с ума. У Вас есть печать, которая включает много переменных, как:

print "$label: $field1, $field2, $field3\n";

И одна из переменных undef. Вы считаете это ошибкой в Вашей программе - вот почему Вы использовали "строгую" прагму. Возможно, Ваша схема базы данных позволила ПУСТОЙ УКАЗАТЕЛЬ в поле, которое Вы не ожидали, или Вы забыли инициализировать переменную, и т.д. Но все сообщение об ошибке говорит Вам, то, что с неинициализированным значением встретились во время конкатенации (.) операция. Если только это сказало Вам имя из переменной, которая была неинициализированной!

, Так как Perl не хочет печатать имя переменной в сообщении об ошибке по некоторым причинам, Вы заканчиваете тем, что разыскали его путем установки точки останова (для рассмотрения, который переменная undef), или добавляющий код для проверки на условие. Очень раздражающий, когда это только происходит одно время из тысяч в сценарии CGI и Вы не можете воссоздать его легко.

15
ответ дан Peter Mortensen 6 November 2019 в 21:04
поделиться

"мои" объявления должны использовать круглые скобки вокруг списков переменных

use strict;
my $a = 1;
mysub();
print "a is $a\n";

sub {
    my $b, $a;   # Gotcha!
    $a = 2;
}

, Это печатает 2 , потому что my объявление только относилось $b (упоминание о $a на той строке просто ничего не сделало). Обратите внимание, что это происходит, не предупреждая, даже когда "использование, строгое", в действительности.

Добавляющие "предупреждения использования" (или флаг-w) улучшает вещи значительно с Perl, говоря Круглые скобки, отсутствующие вокруг "моего" списка . Это показывает, как многие уже имеют, почему и строгие прагмы и прагмы предупреждений всегда являются хорошей идеей.

15
ответ дан Peter Mortensen 6 November 2019 в 21:04
поделиться

Присвоение массивов к скалярам не имеет никакого смысла мне. Например:

$foo = ( 'a', 'b', 'c' );

Присваивает 'c' $foo и бросает остальную часть массива далеко. Этот является более странным:

@foo = ( 'a', 'b', 'c' );
$foo = @foo;

Это похоже на него, должен сделать то же самое как первый пример, но вместо этого это устанавливает $foo на длина из @foo, таким образом $foo == 3.

15
ответ дан Graeme Perrow 6 November 2019 в 21:04
поделиться

Наиболее распространенный глюк должен запустить Ваши файлы с чего-либо различного, чем

use strict;
use diagnostics;

, pjf добавляет: предупредите, что диагностика имеет значительный влияние на производительность. Это замедляет запуск программы, поскольку это должно загрузить perldiag.pod, и до bleadperl с несколько недель назад, это также замедляет и чрезмерно увеличивает размер regexps, потому что это использует $ &. Используя предупреждения и выполнение splain на результатах рекомендуется.

16
ответ дан Community 6 November 2019 в 21:04
поделиться

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

16
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

DWIMmer Perl борется с << (здесь-документ) нотация при использовании print с лексическими дескрипторами файлов:

# here-doc
print $fh <<EOT;
foo
EOT

# here-doc, no interpolation
print $fh <<'EOT';
foo
EOT

# bitshift, syntax error
# Bareword "EOT" not allowed while "strict subs" in use
print $fh<<EOT;
foo
EOT

# bitshift, fatal error
# Argument "EOT" isn't numeric...
# Can't locate object method "foo" via package "EOT"...
print $fh<<'EOT';
foo
EOT

решение состоит в том, чтобы или стараться включать пробел между дескриптором файла и << или снять неоднозначность дескриптора файла путем обертывания его в {} фигурные скобки:

print {$fh}<<EOT;
foo
EOT
18
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

Это - метаответ. Много противных глюков поймано Perl:: Критик , который можно установить и выполнить из командной строки с perlcritic команда, или (если Вы рады отправить свой код через Интернет и не быть в состоянии настроить Ваши опции) через Perl:: веб-сайт Критика .

Perl::Critic также предоставляет ссылки Damian Conways Лучшие практики Perl книга, включая номера страниц. Таким образом, если Вы слишком ленивы для чтения целой книги, Perl::Critic может все еще сказать Вам биты, которые Вы должны считать.

28
ответ дан pjf 6 November 2019 в 21:04
поделиться

Можно распечатать к лексическому дескриптору файла: хороший.

print $out "hello, world\n";

Вы тогда понимаете, что могло бы быть хорошо иметь хеш дескрипторов файлов:

my %out;
open $out{ok},   '>', 'ok.txt' or die "Could not open ok.txt for output: $!";
open $out{fail}, '>', 'fail.txt' or die "Could not open fail.txt for output: $!";

Пока неплохо. Теперь попытайтесь использовать их и печать одной или другому согласно условию:

my $where = (frobnitz() == 10) ? 'ok' : 'fail';

print $out{$where} "it worked!\n"; # it didn't: compile time error

необходимо перенестись, хеш разыменовывают в паре кюри:

print {$out{$where}} "it worked!\n"; # now it did

Это - абсолютно неинтуитивное поведение. Если Вы не слышали об этом или читали его в документации, я сомневаюсь, что Вы могли понять его самостоятельно.

28
ответ дан dland 6 November 2019 в 21:04
поделиться

Большинство операторов цикличного выполнения Perl (foreach, map, grep) автоматически локализуйте $_ но while(<FH>) не делает. Это может привести к странному action-at-a-distance.

14
ответ дан Michael Carman 6 November 2019 в 21:04
поделиться

Забыл добавить путь к каталогу к результатам readdir перед выполнением тестов с этими результатами. Вот пример:

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

opendir my $dh, '/path/to/directory/of/interest'
  or die "Can't open '/path/to/directory/of/interest for reading: [$!]";

my @files = readdir $dh; # Bad in many cases; see below
# my @files = map { "/path/to/directory/of/interest/$_" } readdir $dh;

closedir $dh or die "Can't close /path/to/directory/of/interest: [$!]";

for my $item (@files) {
  print "File: $item\n" if -f $item;
  # Nothing happens. No files? That's odd...
}

# Scratching head...let's see...
use Data::Dumper;
print Dumper @files;
# Whoops, there it is...

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

3
ответ дан 6 November 2019 в 21:04
поделиться

Унарный минус с «foo» создает «- foo» :

perl -le 'print -"foo" eq "-foo" ? "true" : "false"'

Это работает, только если первый символ совпадает с / [_ a-zA-Z ] / . Если первым символом является «-» , тогда он изменяет первый символ на «+» , а если первый символ - «+» , тогда он изменяет первый символ на "-" . Если первый символ совпадает с / [^ - + _ a-zA-Z] / , тогда он пытается преобразовать строку в число и отменяет результат.

perl -le '
    print -"foo";
    print -"-foo";
    print -"+foo";
    print -"\x{e9}"; #e acute is not in the accepted range
    print -"5foo";   #same thing for 5
'

Приведенный выше код печатает

-foo
+foo
-foo
-0
-5

Эта функция в основном существует для того, чтобы люди могли говорить такие вещи, как

my %options = (
    -depth  => 5,
    -width  => 2,
    -height => 3,
);
8
ответ дан 6 November 2019 в 21:04
поделиться

Изменение массива, на который вы наезжаете, в a для(каждого), как в:

my @array = qw/a b c d e f g h/;

for ( @array ) {
    my $val = shift @array;
    print $val, "\n";
}

путается и не делает того, что вы ожидаете

.
-2
ответ дан 6 November 2019 в 21:04
поделиться
Другие вопросы по тегам:

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