2013-07-29 5 views
0

У меня есть этот код, и я получаю предупреждение: Argument "" isn't numeric in numeric eq (==) для $id == $_Аргумент «» не является числовым значением в числовом уравнении (==)

@delete имеет номера данные с веб-формы (запрос CGI), и, вероятно, именно поэтому perl обрабатывает эти числа как строки. Он работает нормально, но я не знаю, что делать с предупреждениями.

my @IDs = (21, 36, 6, 7, 64, 6435, 24); 
for my $id (@IDs) { 
    push @insert, $id if (grep $id == $_, @delete) 
} 

Я не хочу предупреждений. Каков мой лучший вариант?

Я сначала подумал об итерации по массиву и вызвал int для каждого элемента, но мне не понравилась идея.

ответ

2

... вот почему perl обрабатывает эти числа в виде строк

Нет, Perl преобразует ваши данные в число из-за оператора числового равенства ==. Когда он предупреждает о "", это означает, что у вас есть пустая строка, и она будет преобразована в ноль 0. Другими словами, ваш массив @delete содержит пустой элемент.

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

my @IDs = (21, 36, 6, 7, 64, 6435, 24); 
my %ID = map { $_ => 1 } @IDs; 
my @insert = grep $ID{$_}, @delete; 

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

Ваша проблема с пустыми строками останется, но до тех пор, пока у вас нет ключей для пустой строки, вы будете в порядке.

Кроме того, вы должны иметь в виду, почему их называют «предупреждениями». Они есть в качестве признака того, что вы делаете то, что не совсем правильно. Поэтому просто замолчать предупреждения, не зная, почему это очень плохо. В этом случае вам нужно конкретно выяснить, что вы хотите делать с пустыми строковыми значениями. (И другие возможные плохие значения).

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

@delete = grep !/^$/, @delete; 
+0

Какой метод лучше? '@delete = grep!/^ $ /, @delete;' Или '@delete = grep! $ _, @delete;' Хорошее объяснение. Убрал много сомнений. – GrSrv

+1

Спасибо. Ну, '!/^ $ /' И '! $ _' Делают в этом случае противоположность друг другу. Пустая строка является ложным значением, поэтому ее отрицание делает ее правдой.Однако выполнение true/false также опасно, поскольку оно может создавать ложные негативы (если нуль '0' является допустимым значением) и ложные срабатывания (например, буквы или пробелы). Если вы получаете свои значения из веб-формы, вы должны сначала проверить их сначала. В этом случае первое безопаснее, так как оно делает только одно: проверьте, пуста ли строка. – TLP

3

Если 0 не является действительным ID, используйте Grep syntaxt так:

grep { $_ and ($id == $_) } @delete; 

или матч, если $ _ имеет только цифры:

grep { /\d+/ and ($id == $_) } @delete; 
2

Быстрый демо вашей проблемы:

use strict; 
use warnings; 

my @insert; 
my @IDs = (21, 36, 6, 7, 64, 6435, 24); 

my @delete = split//, "1 2 4"; 
warn "this is ok"; 
for my $id (@IDs) { push @insert, $id if (grep { $id == $_ } @delete) } 

warn "now get warning"; 
@delete = split//, "1 2 4"; 
#      ^^ note two spaces - the split will produce one empty element 
for my $id (@IDs) { push @insert, $id if (grep { $id == $_ } @delete) } 

Вам необходимо подтвердить ввод только цифр.

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