Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Perl - начало изучения.


Автор: Vldmir 15.7.2009, 14:29
Всем здарова! smile  По рекомендациям опытных начал изучение Perl по книге Р. Шварца и Т. Кристиансена "Изучаем Perl", но на определённом этапе освоения материала начались сложности. Программа почему то работает не корректно, хотя код в точности совпадает скнижным вариантом, а также были выполнены все пункты по размещению файлов секретных слов с расширением *.secret в рабочем каталоге. Там же были размещены файлы для записи базы данных lastdb.dir и lastdb.pag. Вот код программы:
Код

#!/usr/bin/perl -w
&init_words ( );
   print "What is your name? ";
   $name = <STDIN>;
   chomp ($name) ;
 if ($name =~ /^randal\b/i) {                             # обратно на другой путь :-) 
    print "Hello, Randal! How good of you to be here!\n";
}else {
     print "Hello, $name! \n";                               # обычное приветствие 
     print "What is the secret word? ";
     $guess = <STDIN>;
     chomp $ guess;
   while (! good_word( $name, $guess)) {
     print "Wrong, try again. What is the secret word? ";
     $guess = <STDIN> ;
     chomp $guess;
   } 

     dbmopen (%last_good, "lastdb", 0666);
     $last_good[$name] = time;
     dbmclose (%last_good);
sub init_words {
   while ($filename =<*.secret>) { 
     open (WORDSLIST, $filename) ||
                                                  die "can't open $filename: $!";
    if (-M WORDSLIST < 7) {
        while ($name = <WORDSLIST>) { 
      chomp ($name);
      $word = <WORDSLIST>;
      chomp ($word);
      $words[$name] = $word;
      }
  }else {                                                             # rename the file so it gets noticed
      rename ($filename, "$filename.old") ||
                                                    die "can't rename $filename.old: $!";
   }
close WORDSLIST;
   }
}
sub good_word {
      my($somename,$someguess) = @_;             # перечислить параметры
      $somename =~ s/\W.*//;                              # удалить все символы, стоящие после первого слова
      $somename =~ tr/A-Z/a-z/;                         # перевести все символы в нижний регистр
    if ($somename eq "randal") {                          # не нужно угадывать
     return 1;                                                       # возвращаемое значение — "true"  
   } 
    elsif (($words[$somename] || "groucho") eq $someguess) {
     return 1;                                                       # возвращаемое значение — "true" 
   }else {
      open MAIL, "| mail YOUR_ADDRESS_HERE";
      print MAIL "bad news: $somename guessed $someguess\n";
      close MAIL;
     return 0;                                                       # возвращаемое значение — "false"
   }
}


А вот сведения об ошибках, выдаваемых интепретатором Perl:
http://ipicture.ru/
Так как, пока нехватает опыта самостоятельно решить подобные задачи, обращаюсь за помощью для устранения представленных ошибок.
Заранее благодарен! smile 

Автор: gcc 15.7.2009, 16:05
Код

#!/usr/bin/perl -w

Код

#!/usr/bin/perl


если скрипт маленький, варнинги можно не включать

Автор: Vldmir 15.7.2009, 17:36
Хорошо удалил ключ -w , но программа опять же выполняется некорректно:
http://ipicture.ru/
Хотя введённое имя соответствует секретному слову. Похоже здесь уже прдупреждение выводит командная строка. smile 

Автор: DaemonSuw 15.7.2009, 17:47
      open MAIL, "| mail YOUR_ADDRESS_HERE"; - ну вот эта штука не для винды) перенаправьте просто в файл
хотя может и есть какие нибудь консольные дискриптовые отсыльщики, но у вас ясно они не стоят(

Автор: Vldmir 15.7.2009, 18:16
А где можно почерпнуть информацию о файловых отсыльщиках для винды и об их установке.

Автор: Itsys 15.7.2009, 20:27
Vldmir, ищи sendmail for windows

Автор: Vldmir 15.7.2009, 21:36
Спасибо, будем действовать! smile 

Автор: DaemonSuw 15.7.2009, 21:47
Vldmir, да вы бы не мучались с администрирование винды, а писали бы просто в файл:

Код

open MAIL, ">C://mail.txt";
print MAIL "bad news: $somename guessed $someguess\n";
close MAIL;


MAIL - это дескриптор файла...
print MAIL '' - печать в этот дескриптор, то есть по сути в файл...
close - закрытие файла и сохранение данных
с mail в примере будет тоже самое только с помощью внешней утилиты mail, которая в качестве аргументов получает е-майл и тело письма, если я правильно понял пример... 


Автор: Vldmir 16.7.2009, 12:06
DaemonSuw, cпасибо за совет. В случае использования приведённого выше кода, ясно программа отправляет сообщение в файл при набранном неправильном секретном слове, или если срок со времени создания секретного слова превысил 7 дней. 
 Но что касается отправки сообщения на адрес электронной почты при помощи SendMail, здесь похоже помимо установки самого SendMail, необходима установка веб-сервера.   
 Да, и ещё вопросик при выполнении кода программы:
Код

#!/usr/bin/perl -w
&init_words ( );
   print "What is your name? ";
   $name = <STDIN>;
   chomp ($name) ;
 if ($name =~ /^randal\b/i) {                             # обратно на другой путь :-) 
    print "Hello, Randal! How good of you to be here!\n";
}else {
     print "Hello, $name! \n";                               # обычное приветствие 
     print "What is the secret word? ";
     $guess = <STDIN>;
     chomp $ guess;
   while (! good_word( $name, $guess)) {
     print "Wrong, try again. What is the secret word? ";
     $guess = <STDIN> ;
     chomp $guess;
   } 

     dbmopen (%last_good, "lastdb", 0666);
     $last_good[$name] = time;
     dbmclose (%last_good);
sub init_words {
   while ($filename =<*.secret>) { 
     open (WORDSLIST, $filename) ||
                                                  die "can't open $filename: $!";
    if (-M WORDSLIST < 7) {
        while ($name = <WORDSLIST>) { 
      chomp ($name);
      $word = <WORDSLIST>;
      chomp ($word);
      $words[$name] = $word;
      }
  }else {                                                             # rename the file so it gets noticed
      rename ($filename, "$filename.old") ||
                                                    die "can't rename $filename.old: $!";
   }
close WORDSLIST;
   }
}
sub good_word {
      my($somename,$someguess) = @_;             # перечислить параметры
      $somename =~ s/\W.*//;                              # удалить все символы, стоящие после первого слова
      $somename =~ tr/A-Z/a-z/;                         # перевести все символы в нижний регистр
    if ($somename eq "randal") {                          # не нужно угадывать
     return 1;                                                       # возвращаемое значение — "true"  
   } 
    elsif (($words[$somename] || "groucho") eq $someguess) {
     return 1;                                                       # возвращаемое значение — "true" 
   }else {
      open MAIL, "| mail YOUR_ADDRESS_HERE";
      print MAIL "bad news: $somename guessed $someguess\n";
      close MAIL;
     return 0;                                                       # возвращаемое значение — "false"
   }

 

 когда введено имя и соответствующее ему секретное слово, программа выводит опять тот же запрос:
http://ipicture.ru/
и понятно посылает сообщение в файл, хотя время созданных файлов секретных слов не привышает 7 дней.
Например, если ввести используемое по умолчанию для всех имён секретное слово "groucho" 
прграмма завершается удачно.

Автор: Slauta 21.7.2009, 00:58
Я тож изучаю пэрл по этой книжке, там много неточностей, приходилось подгонять под винду либо пробовать под линукс, но на линуксе проктически 50% всех ошибок, теже что и на винде. Я так думаю, что книжка врод писалась 1998 году, а с тех пор много времени прошло, да и та самая винда изменилась (хотя наверн пэрл не был расчитан на 98 винду, а ток на линуксы). Так что эта книжка хорошэнько тренерует мозги...

Автор: shamber 21.7.2009, 10:37
Цитата(Vldmir @  16.7.2009,  12:06 Найти цитируемый пост)
десь похоже помимо установки самого SendMail, необходима установка веб-сервера.   

почему?

Автор: Vldmir 21.7.2009, 20:33
shamber, поправлюсь, я хотел лишь упомянуть, что сервер можно использовать как один из вариантов проверки удачной отправки почты, применяя Perl-скрипт. Например, в дистрибутив Denver'а входит sendmail для проверки отправки почтовых сообщений. Но также не исключаю, что для выполнения подобной задачи можно применить ряд специальных модулей . 

Автор: KSURi 21.7.2009, 20:37
На самом деле не sendmail, а заглушка, которая пишет в файл. Во всяком случае, так было года два назад)

Автор: Vldmir 21.7.2009, 20:46
 Если я вас правильно понял, то принцип использования sendmail на Denver'е, аналогичен принципу отправки сообщения из Perl- скрипта в файл? 

Автор: shamber 21.7.2009, 22:41
да

Добавлено через 38 секунд
хотите посылать почту смотрите на smtp.

Автор: amg 27.7.2009, 09:51
Vldmir, ошибки в скрипте -- скорее всего из-за не вполне корректного OCR сканированного текста (у Вас же электронный вариант книги?). 

Предупреждения  (опция  -w) отключать не следует, они сильно помогают искать ошибки. 
Например, первое предупреждение на использование неинициализированного $word означает, что в эти переменную из файла ничего не зачиталось. Надо разбираться, почему так, дальнейшая отладка без этого не имеет смысла. 
Следующее предупреждение об использовании слова там где должно быть число -- это явно ошибка OCR: фигурные скобки перепутаны с квадратными. По смыслу должно быть $words{$name} = $word;, т.е. не массив, а хэш. Соответственно, ниже $words{$somename}

Еще одна ошибка -- лишний пробел в chomp $ guess;

По поводу почтовой программы в виндах -- оставьте это на потом, а пока просто замените фрагмент
      open MAIL, "| mail YOUR_ADDRESS_HERE";
      print MAIL "bad news: $somename guessed $someguess\n";
      close MAIL;
на строку
      warn "bad news: $somename guessed $someguess\n";

Успехов!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)