Your SlideShare is downloading. ×
0
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
perl casual #4 大改造!! Perl劇的ビフォーアフター
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

perl casual #4 大改造!! Perl劇的ビフォーアフター

2,672

Published on

http://cpanbook.koneta.org/post/5027293272/perl-casual-4

http://cpanbook.koneta.org/post/5027293272/perl-casual-4

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
2,672
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 本が出ました• m(__)m
  • 2. CONFIDENTIAL @tomitaPerl Casual #4 @tomita
  • 3. アジェンダ• 物件1: バッチ処理• 物件2: メール送信フォーム の使い⽅紹介
  • 4. 物件1 バッチ処理 1
  • 5. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 6. 0 0 1 * * cd /home/app/; perl batch/dump.pl
  • 7. 改善したい点• 動くのだけど・・・
  • 8. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI; パスワードをスクリ$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = プトに書きたくない localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 9. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass); 前⽉指定が怪しい。$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry あと引数で任意の⽉ WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month); を指定したいopen FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 10. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass); 自作CSV出⼒部分の$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry 不安 WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 11. 改善したい点• パスワードをスクリプトに書きたくな い• 前⽉指定が怪しい。• あと引数で任意の⽉を指定したい• 自作CSV出⼒部分の不安• を置いておいて
  • 12. 潜在的な問題
  • 13. p.12
  • 14. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI; use strict;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = use warnings; localtime($month); がない = ケアレス$month = sprintf("%4d%02d", $year+1900, $mon);$db =$st = ミスの可能性 DBI->connect(dbi:mysql:company, $dbuser, $dbpass); $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 15. $dbuser = company-batch; 例外処理不⾜$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 16. $dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7; ⽇本語を含む値($sec, $min, $hour, $mday, $mon, $year) = だった場合 localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);open FH, "> $month.csv";while (my $row = $st->fetchrow_arrayref) { print FH join ",", @$row; print FH "¥r¥n";}
  • 17. 潜在的な問題• use strict; use warnings; がない ←• 例外処理不⾜• ⽇本語を含む値だった場合
  • 18. use strictuse warnings;$dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section
  • 19. perl -c> perl –c dump.plGlobal symbol "$dbuser" requires explicit package name atdump.pl line 5
  • 20. 潜在的な問題• use strict; use warnings; がない• 例外処理不⾜ ←• ⽇本語を含む値だった場合
  • 21. p.246, 247 PRポイント: 全編falseを返すのか、 例外を返すのか、例 外を返すにはどうし たらよいのかを触れ ている
  • 22. p.15
  • 23. use strictuse warnings;use autodie; autodie;my $dbuser = company-batch;my $dbpass = company-batch-pass;use DBI;my $month = time - 60*60*24*7;my ($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);my $db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass,{ RaiseError => 1,});my $st = $db->prepare(q{
  • 24. MAILTO=admin@example.com0 0 1 * * cd /home/app/; perl batch/dump.pl
  • 25. 潜在的な問題• use strict; use warnings; がない• 例外処理不⾜• ⽇本語を含む値だった場合 ←
  • 26. p.248 DBI DBI PRポイント: 全編を通して”⽂字列” を受け取るのか、返 すのかに触れている
  • 27. p.11 凡例
  • 28. my $db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass,{ RaiseError => 1, mysql_enable_utf8 => 1,});...open(my $fh, >:encoding(cp932), $filename); open()の使い⽅ですが openモジュールの項目 で解説しています
  • 29. 改善したい点• パスワードをスクリプトに書きたくな い• 前⽉指定が怪しい。• あと引数で任意の⽉を指定したい• 自作CSV出⼒部分の不安
  • 30. 設定ファイルJSON形式YAML形式INI形式XML形式
  • 31. p.223 App::Options
  • 32. 改善したい点• パスワードをスクリプトに書きたくな い• 前⽉指定が怪しい。• あと引数で任意の⽉を指定したい• 自作CSV出⼒部分の不安
  • 33. use strict;use warnings;use autodie;use DBI; App::Options(use App::Options( option => { filename_format => { ./%s.csv s.csv default => ./%s.csv }, dbuser => { required => 1 }, dbpass => { required => 1 }, month => { required => 1, type => /^20¥d{4}$/ }, /^20¥ });my $db = DBI->connect(dbi:mysql:company, $App::options{dbuser}, App::options{dbuser} $App::options{dbpass}, App::options{dbpass} { RaiseError => 1, mysql_enable_utf8 => 1, },);
  • 34. •dump.confdbuser = company-batchdbpass = company-batch-pass> perl dump.pl --month=201103 --helpUsage: dump.pl [options] [args] --help print this message --dbpass=<value> [********] --dbuser=<value> [company-batch] --filename_format=<value> [./%s.csv] --month=<value> [201103] (/^20¥d{4}$/)
  • 35. 改善したい点• パスワードをスクリプトに書きたくな い• 前⽉指定が怪しい。 ←• あと引数で任意の⽉を指定したい• 自作CSV出⼒部分の不安
  • 36. p.95-p.95- Time::Piece
  • 37. Time::Piece Piece;use Time::Piece;use Time::Seconds; Time::Seconds;use App::Options( option => { filename_format => { default => ./%s.csv }, dbuser => { required => 1 }, dbpass => { required => 1 }, month => { type => /^20¥d{4}$/, default => do { localtime; my $d = localtime; $d- month_last_day; $d -= ONE_DAY * $d->month_last_day; $d- strftime(%Y%m); $d->strftime(%Y%m); }, }, });my $db = DBI->connect(dbi:mysql:company,
  • 38. 改善したい点• パスワードをスクリプトに書きたくな い• 前⽉指定が怪しい。• あと引数で任意の⽉を指定したい• 自作CSV出⼒部分の不安 ←
  • 39. p.202 Text::CSV
  • 40. my $rows = $db->selectall_arrayref(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section}, {}, $App::options{month},);my $filename = sprintf $App::options{filename_format}, $App::options{month};open(my $fh, >:encoding(cp932), $filename); $csv Text::CSV-my $csv = Text::CSV->new({ auto_diag => 1, binary => 1, eol => "¥r¥n", "¥});$csv->print($fh, $_) for @$rows; csv- print($fh,
  • 41. なんということでしょう〜•before$dbuser = company-batch;$dbpass = company-batch-pass;use DBI;$month = time - 60*60*24*7;($sec, $min, $hour, $mday, $mon, $year) = localtime($month);$month = sprintf("%4d%02d", $year+1900, $mon);$db = DBI->connect(dbi:mysql:company, $dbuser, $dbpass);$st = $db->prepare(q{ SELECT section, COUNT(*) AS count FROM inquiry WHERE DATE_FORMAT(ctime, "%Y%m") = ? GROUP BY section});$st->execute($month);
  • 42. なんということでしょう〜•afteruse strict;use warnings; https://gist.github.com/956691use autodie;use DBI;use Text::CSV;use Time::Piece;use Time::Seconds;use App::Options( option => { filename_format => { default => ./%s.csv }, dbuser => { required => 1 }, dbpass => { required => 1 }, month => { type => /^20¥d{4}$/, default => do { my $d = localtime;
  • 43. 導⼊したモジュール• strict• warnings• autodie• Text::CSV• Time::Piece• App::Options
  • 44. モジュールのインストール• → p.421- App::cpanminus
  • 45. App::cpanminusの項目で取り上げてApp::cpanminusいる内容• cpanmコマンド自体の導⼊⽅法• インストールパスの確認⽅法• 特定のディレクトリにインストールす る⽅法(ユーザー権限で)• インストール失敗時のトラブルシュー ティング
  • 46. > cpanm -l extlib autodie Text::CSV Time::Piece App::Optionsuse strict;use warnings;use FindBin; FindBin;use lib "$FindBin::Bin/extlib/lib/perl5";use autodie;use DBI;use Text::CSV;use Time::Piece;use App::Options(> perl -Mlib="extlib/lib/perl5/" dump.cgi
  • 47. 物件2 メール送信フォーム 2
  • 48. 割愛
  • 49. 割愛
  • 50. 1ページ目のサンプルがほとんど• strict/warningsに通らない• jcode.pl付属(2005年以前?)• メールのソースを⼿作り• 自作のバリデーション• エラー⽂⾔が送信プログラムに書いてある• ※だめというわけではありません
  • 51. 改造• というよりは作り直しの例
  • 52. サーバー サーバー・バリデーション ・バリデーション ・処理(メール送信)
  • 53. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="stylesheet" href="http://static.koneta.org/base.css" type="text/css" /><title>お問い合わせフォーム</title></head><body><h1>お問い合わせフォーム</h1> https://gist.github.com/956691<form method="post" id="form"> <p>お名前<br /> <input type="text" class="input text" name="name" /></p> <p>メールアドレス<br /> <input type="text" class="input text ascii" name="email" /></p> <p>お問い合わせ内容<br /> <textarea class="input" name="comment"></textarea></p> <p class="notice message hide">入力内容を確認してください。</p> <p class="error message hide">送信失敗しました。info@koneta.orgまで送信願います。</p> <p class="information message hide step2">この内容で送信してもよいですか?</p> <button type="submit" class="step1" value="2">確認</button> <button type="submit" class="step2 hide" value="1">修正</button> <button type="submit" class="step2 hide" value="3">送信</button></form> <p class="success message hide step3">お問い合わせありがとうございました。</p></body></html>
  • 54. サーバーサイド• JSON作成• JSON RPC サーバー• ⼊⼒値バリデーション• メール作成• メール送信• 割愛: トークン、丁寧なエラー
  • 55. サーバーサイド• JSON作成 ←• JSON RPC サーバー• ⼊⼒値バリデーション• メール作成• メール送信
  • 56. p.180 JSON
  • 57. use JSON;my $res = { version => 1.1 };if (my $error = validate($req)) { $res->{error} = $error;}if ($res->{validate} and $req->param(step) eq submit) { $res->{result} = sendmail($req);} encode_json($res);my $body = encode_json($res);
  • 58. サーバーサイド• JSON作成• JSON RPC サーバー ←• ⼊⼒値バリデーション• メール作成• メール送信
  • 59. Plack::Request;use Plack::Request;my $app = sub { $req Plack::Request- new(shift); my $req = Plack::Request->new(shift); my $res = { version => 1.1 }; if (my $error = validate($req)) { $res->{error} = $error; } if ($res->{validate} and $req->param(step) eq submit) { $res->{result} = sendmail($req); } my $body = encode_json($res); return [ 200, Content- application/json json [ Content-Type => application/json ], [ $body ], ];};
  • 60. なんということでしょう〜•before 割愛
  • 61. なんということでしょう〜•afteruse strict;use wanings;use JSON https://gist.github.com/956691use Plack::Request;my $app = sub { my $req = Plack::Request->new(shift); my $res = { version => 1.1 }; if (my $error = validate($req)) { $res->{error} = $error; } if ($res->{validate} and $req->param(step) eq submit) { $res->{result} = sendmail($req); }
  • 62. p.334, 335 Plack
  • 63. サーバーサイド• JSON作成• JSON RPC サーバー• ⼊⼒値バリデーション ←• メール作成• メール送信
  • 64. p.346 FormValidator::Lite• おすすめ理由 http://d.hatena.ne.jp/tomi-ru/20110119/1295394476
  • 65. なんということでしょう〜•before 割愛
  • 66. •after qw/Email/;use FormValidator::Lite qw/Email/;sub validate { my ($req) = @_; ($req) req FormValidator::Lite- new($req); my $form = FormValidator::Lite->new($req); $form- $form->check( email => [REQUIRED, EMAIL], comment => [REQUIRED], ); $form- has_error; return unless $form->has_error; return { name ValidateError ValidateError, => ValidateError, code => 100, message => Validate Error, };}
  • 67. サーバーサイド• JSON作成• JSON RPC サーバー• ⼊⼒値バリデーション• メール作成 ←• メール送信
  • 68. なんということでしょう〜•before 割愛
  • 69. •afteruse utf8;use Encode;use Email::MIME; Email::MIME; Email::MIME-my $email = Email::MIME->create( header => [ From => $req->param(email), $req param(email), req- To info@koneta.org info@koneta.org, => info@koneta.org, Subject => [問い合わせフォーム], [問 わせフォーム], フォーム ], attributes => { charset iso-2022- => iso-2022-jp, encoding => 7bit, }, sprintf( body_str => sprintf( "[Name]¥n%s¥ n[Comment]¥n%s", "[Name]¥n%s¥n¥n[Comment]¥n%s", $encoding- $req param(name) req- $encoding->decode( $req->param(name) ), $encoding- $encoding->decode( $req->param(comment) ), $req param(comment) req- ),);
  • 70. サーバーサイド• JSON作成• JSON RPC サーバー• ⼊⼒値バリデーション• メール作成• メール送信 ←
  • 71. なんということでしょう〜•before 割愛
  • 72. •afteruse Email::Send; Email::Send;my $sender = Email::Send->new({ mailer => Sendmail }); Email::Send- Sendmail Sendmail$sender- send($email)$sender->send($email) or die "send() failed!";
  • 73. CONFIDENTIALありがとうございました。
  • 74. • http://twitter.com/tomita
  • 75. One More• ⼀⽅ロシアは・・・• テスト

×