Автор Тема: Помогите "объяснить" самому себе ошибку  (Прочитано 4603 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Вот код


sub copy_mess_head 
{

my $mail =shift @_;

my $line;

my $result = -1;
my @cc $mail->header("cc");

if (!
undef $cc[-1]) {
	
foreach 
my $str (@cc) {
	
	
if (
undef $str){
	
	
	
if ((
$str ne \'\')or ($str ne \' \')) {
	
	
	
	
$line = "$line$str";
	
	
	
}
	
	
}
	
}
}

@cc = ();

@cc = $mail->header("CC");

if (!undef $cc[-1]) {
	
foreach my $str (@cc) {
	
	
if (undef $str){
	
	
	
if (($str ne \'\')or ($str ne " ")) {
	
	
	
	
$line = "$line$str";
	
	
	
}
	
	
}
	
}
}

if (undef $line) {      ###### это 77 строка . Здесь ругается.
	
$result = $line;
}
elsif ($line eq \'\') {
	
$result = -1;
}
return  $result;
}



в результате работы выдается такое вот сообщение
[root@skif.bsd] /usr/local/script/filters/:chmod 755 ./my_filter.pl && ./my_filter.pl
Use of uninitialized value in string eq at ./my_filter.pl line 77.

Я немогу понять, почему? Ведь это как раз проверка на то, определена переменная или нет. А идет ругань....
Всё будет хорошо - я договорился!

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
Помогите "объяснить" самому себе ошибку
« Ответ #1 : 31 Мая 2005, 13:49:42 »
perldoc -f undef
perl -de0

  DB<1> $test = 1

  DB<2> undef $test

  DB<3> print $test
The documentations is your friend

Оффлайн commander

  • Developer
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1298
  • +0/-0
  • 2
    • Просмотр профиля
    • http://www.webtips.ru
Помогите "объяснить" самому себе ошибку
« Ответ #2 : 31 Мая 2005, 13:51:31 »
Skif
если бы логическая конструкция была такой:
if (undef $line)
{
$result = $line;
}
else
{
$result = -1;
}
ругани бы не было...
выводы делаем сами... ;)
And no religion too...

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите "объяснить" самому себе ошибку
« Ответ #3 : 31 Мая 2005, 13:53:25 »
да ступил, надо
!undef
Всё будет хорошо - я договорился!

Оффлайн Mog.

  • Фанат форума
  • Ветеран
  • *****
  • Сообщений: 828
  • +0/-0
  • 0
    • Просмотр профиля
Помогите "объяснить" самому себе ошибку
« Ответ #4 : 31 Мая 2005, 13:53:57 »
undef $line делает переменную $line неопределенной
для проверки надо
if(defined $line)
Все болезни от нервов, только сифилис от удовольствия

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите "объяснить" самому себе ошибку
« Ответ #5 : 31 Мая 2005, 14:00:35 »
нет, сегодня я определенно торможу - надо использовать define замутил не ту функцию :)
Всё будет хорошо - я договорился!

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите "объяснить" самому себе ошибку
« Ответ #6 : 31 Мая 2005, 14:07:28 »
выглядеть все должно так:


sub copy_mess_head 
{

my $mail =shift @_;

my $line;

my $result 1;
my @cc $mail->header("cc");

if (
defined $cc[-1]) {
	
foreach 
my $str (@cc) {
	
	
if (
defined $str){
	
	
	
if ((
$str ne \'\')or ($str ne \' \')) {
	
	
	
	
$line = "$line$str";
	
	
	
}
	
	
}
	
}
}

@cc = ();

@cc = $mail->header("CC");

if (defined $cc[-1]) {
	
foreach my $str (@cc) {
	
	
if (defined $str){
	
	
	
if (($str ne \'\')or ($str ne " ")) {
	
	
	
	
$line = "$line$str";
	
	
	
}
	
	
}
	
}
}
if ($line eq \'\') {
	
$result = 1;
}
elsif (defined $line) {
	
$result = $line;
}
else {
	
$result = 1
}
return  $result;
}
Всё будет хорошо - я договорился!

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Помогите "объяснить" самому себе ошибку
« Ответ #7 : 31 Мая 2005, 14:49:44 »
Skif

В такой конструкции, warning получишь сразу


...
if (
$line eq \'\') { 
    $result = 1; 

elsif (defined $line) { 
    $result = $line; 

else { 
    $result = 1 

return  $result;
... 


И последнее условие немного странное... переменная может быть либо определена, либо не определена, но никак не "наполовину определена".

Проще всего записать так, и не морочится:

$result $line || 1;
« Последнее редактирование: 31 Мая 2005, 15:01:30 от Phoinix »

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Помогите "объяснить" самому себе ошибку
« Ответ #8 : 01 Июня 2005, 10:52:45 »
Вот эта конструкция вообще надуманная:


if (defined $cc[-1]) {
    foreach 
my $str (@cc) {
        if (
defined $str){
            if ((
$str ne \'\')or ($str ne \' \')) {
                $line = "$line$str";
            }
        }
    }
}

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

foreach my $str (@cc) {
        $str=~s/^\\s//;
        $line = "$line$str" if(length($str)>0);
    }
« Последнее редактирование: 01 Июня 2005, 10:58:46 от cr4ck3r »
Ворота в perl - perlmonks.org.ru

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите "объяснить" самому себе ошибку
« Ответ #9 : 01 Июня 2005, 15:36:44 »
Phoinix

нет, такой вариант не подходит.  $line может принимать три вида значений undef, \'\' и строку(символ). Во всех случаях кроме строки - мне нужно вернуть результат = 1, в случае строки - вернуть строку. (пример ниже)
cr4ck3r
частично согласен. Но мне еще надо проверить имеется ли пустой символ.

вот пример:

#!/usr/bin/perl -w

$a=\'\';
$b=\'\';
$c=\'\';

push @arr, $a;
push @arr, $b;
push @arr, $c;


$size = @arr;

print "$size\\n";
exit(0);



а вот что он возвращает:
Цитировать

[root@skif.center.klo] /usr/local/script/:./1.pl
3


тобишь проверка на "пустиой символ" мне просто необходима.
Всё будет хорошо - я договорился!

Оффлайн Skif

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 187
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите "объяснить" самому себе ошибку
« Ответ #10 : 01 Июня 2005, 15:49:03 »
cr4ck3r
$line = "$line$str" if(length($str)>0);
Невнимательный был. Да ты прав, эта конструкция проще.
Всё будет хорошо - я договорился!

Оффлайн Phoinix

  • RW
  • Ветеран
  • *****
  • Сообщений: 1097
  • +0/-0
  • 2
    • Просмотр профиля
    • http://phoinix.ucoz.ru
Помогите "объяснить" самому себе ошибку
« Ответ #11 : 01 Июня 2005, 18:20:16 »
Skif

Цитировать
нет, такой вариант не подходит. $line может принимать три вида значений undef, \'\' и строку(символ). Во всех случаях кроме строки - мне нужно вернуть результат = 1, в случае строки - вернуть строку. (пример ниже)


Для самопроверки:
#!/usr/bin/perl -w
use strict;

    
my $var1 = \'2\';
    my $var2 = $var1 || 1;
    print $var2, "\\n";

    $var1 = \'\';
    $var2 = $var1 || 1;
    print $var2, "\\n";

    $var1 = undef;
    $var2 = $var1 || 1;
    print $var2, "\\n";

exit;

Результат:

2
1
1

Как раз то что нужно...

cr4ck3r

Еще немного упростить:

foreach my $str (@cc) {
        
$str=~s/^\\s//;
        
$line .= $str if length($str) > 0;
}

Оффлайн cr4ck3r

  • Фанат Perl
  • Постоялец
  • ***
  • Сообщений: 146
  • +0/-0
  • 2
    • Просмотр профиля
    • http://perlmonks.org.ru
Помогите "объяснить" самому себе ошибку
« Ответ #12 : 02 Июня 2005, 10:09:38 »
Цитировать
Phoinix:
Еще немного упростить:


foreach my $str (@cc) {
$str=~s/^\\s//;
$line .= $str if length($str) > 0;
}

5 баллов :)
Ворота в perl - perlmonks.org.ru

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28