Archive for the 'Perl' Category

『YAPC::Asia 2008』に行ってきました

2008年05月16日 written by fjkktkys

Perlのカンファレンス、YAPCに行ってきました。

とりあえずPerlコミュニティのノリだけをお伝えする目的で今回のエントリを書いています。
Perlの開発者であるLarry Wallの基調講演と弾さんのトークの各イントロ部分をYouTubeにアップしてみました。Perlとかがよくわからなくてもノリだけは伝わるのではないかと思います。

ズームしてますので画質は悪いです。あしからず。手ブレすみません。自分の笑い声入っててすみません。

今年はフレームワークの話が減少して、データまわりの話が少し増えたのかなあという印象でした。ネタも相変わらず素敵でした。

「第一回DeNAテクノロジーカンファレンス」に行ってきました

2008年02月16日 written by fjkktkys

DeNA テクノロジーセミナーへのお誘い - DeNA 技師のメモ

運良く抽選に当たり参加させていただきました。簡単な報告エントリです。

内容に関しては、以下のサイトが良くまとまっていると思います。
第一回DeNAテクノロジーカンファレンス[DeNA][モバゲー][MySQL] - d.hatena.zeg.la

開始直後からDeNAのテクノロジーチームのオープンな雰囲気に衝撃を受け続けていました。
懇親会で技術的な部分で使っているものなどの質問をさせていただきました。オープンにすることの価値を理解してはいたつもりですが、質問に対して全く情報を隠さない姿勢に圧倒されました。あと「Perlいいですよね〜」的なことばかり喋っててすみませんでした。

あのようなオープンな雰囲気を作るのって簡単なことではないでしょう。そこに凄みを感じた次第です。久しぶりに自分のレベルの低さを痛感させられた感じでした。

参加させていただきありがとうございました。

WWW::MechanizeとMIME::Liteで作るメール報告ツール

2008年02月10日 written by fjkktkys

それPlaggerでと言われそうですが、かなり今更感がありますけど、Plaggerはそれなりに敷居が高い気がします。

お題はアマゾンアフィリエイトのメール報告ツールです。これを自動化する目的は、ログインから各報告ページまでのクリックなどが、個人的には面倒だなあという感じがするからです。

以下のコードのemailとpassword部分を必要なものに変えて使ってみてください。ログインして、各ページの必要な部分をdivタグごと抜き出してそれをHTMLに適当に切り貼りして(編集メンドイ)、HTMLメールにして送るというだけのものです。

正規表現の替わりにWeb::Scraperを使うのも良さそうです。

#ちなみにAmazon側でリンクのURLの順番などが替わったら、follow_linkの内容を変えないといけません。follow_linkでurlやregex_textを直接指定してもうまくいかなく、さっくり諦めました。

CODE:
  1. #!/usr/local/bin/perl
  2. use strict;
  3. use WWW::Mechanize;
  4. use MIME::Lite;
  5.  
  6.  
  7. my $url = 'https://affiliate.amazon.co.jp/gp/associates/login/login.html';
  8. my $mech = WWW::Mechanize->new(agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
  9. # login form
  10. $mech->get($url);
  11.  
  12.  
  13. # login
  14. $mech->submit_form(
  15.   form_number => 1,
  16.   fields      => {
  17.     email => 'your@email.address',
  18.     password => 'yourpassword',
  19.   },
  20. );
  21. my $total = ( $mech->content() =~ /(<div id=\"sidebar\">.*?)<div id=\"content\" class=\"withSidebar\">/s )[0];
  22. # revenue page
  23. $mech->follow_link( n => 14 );
  24. my $revenue = ($mech->content() =~ /(<div class=\"reporttext\">(.*?)<\/table>)/s)[0];
  25. # ordered page
  26. $mech->back();
  27. $mech->follow_link( n => 15 );
  28. my $ordered = ($mech->content() =~ /(<div class=\"reporttext\">(.*?)<\/table>)/s)[0];
  29. my $css = ($mech->content() =~ /(<link rel=\"stylesheet\".*?\/>)/)[0];
  30. my $html = "<html><head>$css<\/head><body>$total<hr>$revenue<hr>$ordered<\/body><\/html>";
  31. my $msg = MIME::Lite->new(
  32.     From     => 'bla@bla.bla',
  33.     To       => 'your@email.address',
  34.     Subject  => 'amazon affiliate report',
  35.     Type     => 'text/html',
  36.     Data     => $html,
  37. );
  38. $msg->send;

続ける.jpを公開しておきます

2007年07月24日 written by fjkktkys

Catalystの習作として作ったアプリを数ヶ月放置していたのでちゃんと紹介しておこうと思います。

続ける.jp - 習慣を作る 三日坊主にならない 毎日のルーチンワーク管理に

ちょっと動作が重くて残念ですが、善処していきたいと思います。
構成はLighty+FastCGI+MySQLです。

要望などは続ける.jp 開発ブログの方までお願いいたします。

なおデザインを入れてくださるという奇特な方を大歓迎しておりますので、我こそはという奇人変人がおりましたら、何卒よろしくお願いいたします。

# ideamiのとりあえず公開した姿勢に倣ったのは言うまでもありません。

(追記)
不調につきまして。
アクセスできない状態になっていたと思われますが、サーバのCPUが100%振り切っておりました。
実は、FastCGIを使うと自分はこの現象にかなり遭遇します。プログラムかサーバの管理まわりがヘボいのが原因だとは思いますが。。。しばらく不便をおかけします。

PHPのPDOのprepareについて

2007年06月09日 written by fjkktkys

スクリプトのprepareとサーバのprepare

PHPのPDOを使いながらクエリーログを見ていたら、
見慣れないものが目に入ってきました。

CODE:
  1. 391 Connect     admin@localhost on pdo_test
  2. 391 Prepare     [1] INSERT INTO users SET name = ?
  3. 391 Execute     [1] INSERT INTO users SET name = '9f732d76d9f2f0b4e62c8091c99a2334'
  4. 391 Quit

Prepareという行なのですが、PerlのDBIを使っていた分には見たことがありませんでした。

そこで以下を参照して、
MySQL 関数 (PDO_MYSQL)

CODE:
  1. $pdo = new PDO('mysql:host=localhost;dbname=pdo_test;charset=utf-8;unix_socket=/tmp/mysql.sock', "username", "password");
  2. $pdo->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, true);

上のようにPDOの設定をして同じSQLを実行すると

CODE:
  1. 392 Connect     admin@localhost on pdo_test
  2. 392 Query       INSERT INTO users SET name = 'f071c916f507876b8f67735faa0e015f'
  3. 392 Quit

いつものようなログが取れましたとさ。

ここで認識できるのは、スクリプト側でのprepareとMySQLサーバサイドでのprepareが別物だということ。恥ずかしながらそうとも知らずに今までPerlのDBIでprepareを使っておりました。
(prepareを使う理由は、プレースホルダーを使って外部入力を安全にSQLに挿入するためです。)

ベンチマークしてみる

で、以下のようなSQLを用意して、
init.sql

CODE:
  1. USE pdo_test;
  2.  
  3. DROP TABLE IF EXISTS users;
  4. CREATE TABLE users (
  5.     id   INT(16) PRIMARY KEY AUTO_INCREMENT,
  6.     name VARCHAR(32) UNIQUE NOT NULL
  7. );

以下のような、スクリプトを用意します。
pdo_test.php

CODE:
  1. <?php
  2. $pdo = new PDO('mysql:host=localhost;dbname=pdo_test;charset=utf-8;unix_socket=/tmp/mysql.sock', "username", "password");
  3. //$pdo->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, true);
  4.  
  5.  
  6.  
  7. //foreach ( range(1, 100000) as $i) {
  8. insertByPrepare($pdo);
  9. //insertByQuery($pdo);
  10. //}
  11.  
  12. //insertByPrepareLoop($pdo);
  13.  
  14. function insertByPrepare ($pdo) {
  15.     $sth = $pdo->prepare("INSERT INTO users SET name = ?");
  16.     $sth->execute( array(hash('md5', microtime())) );
  17. }
  18.  
  19. function insertByQuery ($pdo) {
  20.     $pdo->query("INSERT INTO users SET name = '" . hash('md5', microtime()) . "'");
  21. }
  22.  
  23. function insertByPrepareLoop ($pdo) {
  24.     $sth = $pdo->prepare("INSERT INTO users SET name = ?");
  25.     foreach ( range(1, 100000) as $i) {
  26.         $sth->execute( array(hash('md5', microtime())) );
  27.     }
  28. }
  29. ?>

ベンチマークには疎いので、適当で手動なんですが、
このスクリプトのコメントアウトのあたりを外したりつけたりして、
コマンドラインから以下を繰り返しです。

CODE:
  1. # mysql <init.sql
  2. # time php pdo_test.php

結果

当たり前ですが、prepareしたステートメントハンドラをループで回すという、
prepareの意味通りに使うパターンが一番早くなりました。

insertByQuery [PDO::MYSQL_ATTR_DIRECT_QUERY, true]
php pdo_test.php  10.14s user 4.24s system 32% cpu 44.907 total

insertByQuery
php pdo_test.php  13.83s user 8.65s system 33% cpu 1:07.68 total

insertByPrepareLoop [PDO::MYSQL_ATTR_DIRECT_QUERY, true]
php pdo_test.php  8.48s user 4.03s system 30% cpu 41.258 total

insertByPrepareLoop
php pdo_test.php  8.14s user 4.40s system 30% cpu 40.570 total

insertByPrepare [PDO::MYSQL_ATTR_DIRECT_QUERY, true]
php pdo_test.php  12.84s user 4.34s system 34% cpu 49.931 total

insertByPrepare
php pdo_test.php  18.05s user 10.15s system 36% cpu 1:17.68 total

ループを回さないところでprepareをすると少し遅いようです。
基本的に「PDO::MYSQL_ATTR_DIRECT_QUERY, true」にしておいて、サーバ側でprepareしないようにしておくと良さそうですね。

#余談
PHP5.1.xだと、LIMITなどで

CODE:
  1. $sth = $pdo->prepare('SELECT * FROM users LIMIT ?');

とやるとステートメントハンドラ自体が帰ってきません。
5.2.xでは解決されているバグのようです。