日向夏特殊応援部隊

俺様向けメモ

Pod ドキュメントを除外してソースのみを見る

それ perldoc -M と Pod::Strip で出来ます。

例えば、

$ perldoc -MPod::Strip AnyEvent

みたいな感じですね。AnyEvent の pod 部が多過ぎてソース読むのが大変だったので、これで読みやすくなりますね。
ひょっとしたらもっと良い、あるいはシンプルな方法があるやもしれないので知ってる人が居たら是非教えて下さいまし。

Lion での EV(libev) のインストール

どうも Lion 環境下だとそのまま EV-4.03 はインストール出来ないみたいですね。

llvm-gcc のバグが原因だそうで、

$ perl Makefile.PL CC=gcc

としてインストール出来ましたとさ!

YAPC Asia 2011 でのスライド公開と感想など

まずは自分のスライドですが公開しました。

ちょっと MacPowerPoint のせいかどうか分からないけどスライドがプロジェクタに映らず急遽 PDF に変換したりして、最大化出来なかったりしてお見苦しい所があったかもしれません。

運営側の一員としては今回は、恒例のノベルティ詰め番長と懇親会担当をやらせて頂きました。
懇親会ですが去年の反省を生かして料理をなるべくお腹に溜まる物としてみたんですが、結構余ってしまいましたね。。。さらに言うとビールが全然足りなくなるという感じで、バランス問題はなかなか難しいなと思いました。この点は来年にまた活かしたいなと思います。

スライドの内容についてはまたどこかで補足・説明したいなと思います。
取り急ぎ、運営に携わった JPA のメンバー及びボランティアスタッフの皆さん。素敵な発表をして頂いたスピーカーの皆さん、お越し頂いた皆さんに感謝です。

しかし、だいちゃんとゆうちゃんの息がばっちりでしたね。
お疲れさまでした。

変数とストアドプロシージャについて

追記しました (2011-08-08T16:57:50Z)

割と弊社では MySQL の event scheduler を使ってみたり、ストアドプロシージャ、トリガーなど積極的に使っています。
今回はストアドプロシージャを書く上で、変数を色々使うのですが備忘録としてメモっておきます。

MySQL における変数には幾つか種類があります。

  • システム変数 (c.f. @@version)
  • ユーザー変数 (c.f. @var_name)
  • ローカル変数 (c.f. DECLARE var_name INT, ストアドプロシージャ内で使える)

これら変数の特徴は下記です。(MySQL 5.1.50 で確認)

-- システム変数 ユーザー変数 ローカル変数
スコープ GLOBAL *1 SESSION LOCAL
なし なし あり
宣言 なし なし あり
設定 SET GLOBAL / SET SESSION SET SET
SELECT INTO 不可
EXECUTE USING 不可 不可

一応幾つか説明しておくと、まずは SELECT INTO ですけど、

SELECT foo, bar INTO @foo_value, @bar_value FROM sample WHERE id = 10;

とかやると foo, bar の値がそれぞれ @foo_value, @bar_value に突っ込まれます。

次に EXECUTE USING ですけど、

SET @sample_id = 1;
PREPARE stmt FROM 'SELECT * FROM sample WHERE id = ?';
EXECUTE stmt USING @sample_id;
DEALLOCATE PREPARE stmt;

みたいな感じで事前に作った placeholder 付きのステートメントを EXECUTE で値を bind して使う事が出来ますが、残念ながらローカル変数をここに用いてはいけません。

考え方にもよりますが、最近のストアドプロシージャ内での編数の使い方として DECLARE で宣言した変数はテーブルのカラム名と区別出来る命名にしないとややこしくて分からなくなるのと、
placeholder への bind に使えないのでユーザー変数だけの利用に原則とどめています。

追記 (2011-08-08T16:57:50Z)

2011-08-06 - tsucchiの日記 で言及されてたのでちょっと触れておきます。

1. あんまり早くない

    • 対比として DBI を使ったスクリプトならば、アドバンテージがあるとしたらネットワークを介してクエリを打ち込まなくなる程度の物しか無いですね。なので大して早く無いというのは概ね同意です

2. スローログの件

    • そもそもスローログに載るような用途には使ってないので、この点に関してはなるほどなぁと言う感じです。

3. コンパイルエラーの件

    • これどうにかなりませんかねぇ。

4. テストが書きにくい

    • それ Test::Fixture::DBI で出来るよ

とまぁ、大体 id:tsucchi1022 さんと同じ意見ではあるのですが、弊社で使っている用途について簡単に説明すると現時点では、

1. Partition の add, drop を procedure + event scheduer で実施している
2. Trigger の内部で呼び出したりしている
3. 最近は Purge をプロシージャでやってたりする

    • Purge の度に書き捨てのスクリプト作るのもなんだかなぁと最近思ってたので。

いずれにせよ、Experimental な使い方している感は多々あります。Purge に関しては sql_log_bin = 0 としてバイナリログを無効化し、すべてのマスタとスレーブで同じ purge 用の procedure を叩いたりしてます。

*1:ただし SET SESSION 文の場合は SESSION 単位

SET TIMESTAMP 構文で時刻の固定

SELECT * FROM hidek WHERE created_on < UNIX_TIMESTAMP() - ? ORDER BY created_on ASC LIMIT 100;

とかそういうクエリをテストしたい場合、Fixture の日時が固定値だと色々と不都合がありますね。

そういう時は、http://dev.mysql.com/doc/refman/5.1/ja/set-option.html にある SET 構文の SET TIMESTAMP を使うとセッションごとに UNIX_TIMESTAMP(), NOW() の値を固定出来ます。

root@localhost[test]:14> SET TIMESTAMP = 1302447600;
Query OK, 0 rows affected (0.00 sec)

root@localhost[test]:15> SELECT UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
|       1302447600 |
+------------------+
1 row in set (0.00 sec)

root@localhost[test]:12> SET TIMESTAMP = DEFAULT;
Query OK, 0 rows affected (0.00 sec)

root@localhost[test]:13> SELECT UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
|       1305711386 |
+------------------+
1 row in set (0.00 sec)

こんな感じアル!

Iterator::GruopedRange 0.02 Released

さて、ちょっとしたことからタイトルのようなモジュールを書いて見ました。Iterator::GroupedRange モジュールは簡単に説明すると、リストまたは別の(複数行ずつ返す)イテレータから指定行数分まとめて列挙するというモジュールです。

0.01 で SYNOPSIS を思いっきり間違えてたので、正しいものをこちらに。*1

use Iterator::GroupedRange;

my @ds = (
  [ 1 .. 6 ],
  [ 7 .. 11 ],
  [ 11 .. 25 ],
);

my $i1 = Iterator::GroupedRange->new( sub { shift @ds; }, 10 );
$i1->next; # [ 1 .. 10 ]
$i1->next; # [ 11 .. 20 ]
$i1->next; # [ 21 .. 25 ]

my $i2 = Iterator::GroupedRange->new( [ 1 .. 25 ], 10 );
$i2->next; # [ 1 .. 10 ]
$i2->next; # [ 11 .. 20 ]
$i2->next; # [ 21 .. 25 ]

例えばこんな風に使います。

my $ids = $dbh_friend->selectcol_arrayref('SELECT friend_user_id FROM friends WHERE user_id = ?', +{ Columns => [1] }, 10028);
my $iterator = Iterator::GroupedRange->new( $ids, 1000 );
my @rs;
while ( $iterator->has_next ) {
  my $ranged_ids = $iterator->next;
  push(@rs, $dbh_owneres->selectcol_arrayref(
    sprintf('SELECT owner_user_id FROM user_application WHERE application_id = ? AND owner_user_id IN (%s)', substr('?,' x @$ranged_ids, 0, -1)),
    +{ Columns => [1], },
    @$ranged_ids,
  ));
}

ちなみに下記のように、やろうと思えばこれらの入れ子なんかも出来ます。

sub installed_users_iterator {
  my ($self, $uids) = @_;
  my $uids_iterator = Iterator::GroupedRange->new( $uids, 1000 );
  my $dbh = $self->dbh;
  return Iterator::GroupedRange->new(sub {
    return [] unless ( $uids_iterator->has_next );
    my $ranged_uids = $uids_iterator->next;
    $dbh->selectcol_arrayref( "SELECT ...", +{ Columns => [1] }, @$ranged_uids );
  }, 1000);
}

この例だと selectcol_arrayref() の実行結果が1000レコードに満たない配列リファレンスが返って来たとしても、高々1000件ずつ取得出来る Iterator を返すと言う感じです。

つまりこれ何のために作ったかと言うと、分割可能なクエリを物理的に異なるDBなどに対して順番にぶつけていくような処理に使えるかなと思って書いた次第です。その際に出来る限りクエリの発行回数を減らす為に書いてみた訳です。

と言うわけでドキュメントが無くてだいぶ酷い状態ですけど、よろしければご利用下さいませ。

*1:そして今気づいたけど method に関する POD が無かったことに気づいた><

クリンスイの蛇口直結型浄水器買った

巷で水道水から200Bq/kgだかのヨウ素131が検出されただとかって話が出ている件ですが、これがどの程度危険な数値なのかどうか、あるいは甲状腺に対する悪影響、特に乳幼児に対して宜しくないらしいとの事のようですね。

ちょうどマンションにある蛇口直結型の浄水器の電池が切れた上にどこのメーカーか分からずフィルタ交換も出来ないし、ミネラルウォーターも売り切れまくってる状況なのでどうしたもんかなと思った結果、クリンスイの蛇口直結型浄水器を買いましたよってあさましエントリですよ!

前から日本ガイシの、

が欲しいなーと思ってたんですけど、これは活性炭のみみたいですね。

C1浄水器放射性物質除去性能に関するお問い合わせについて

 お客さまからC1浄水器ヨウ素セシウムなどの放射性物質を除去できるのかとのお尋ねをメールでいただき、一部推定を交えたお答えをしたところ、多くの反響があり、たくさんの方からお問い合わせをいただきました。
 当社の浄水器は水道水水質基準を満たす水をろ過することを前提に製造されており、国の指定する有害13物質の除去性能については確認をしております。しかし、現在問題となっている放射性物質をどれくらい除去できるかについての実証的なデータはございません。
 活性炭のなかには、高い放射性物質吸着性能を有するものがあり、C1浄水器にも活性炭を使用しているため、一般論として推定を交えたお答えをいたしましたが、C1浄水器に使用している活性炭が水道水中の放射性物質を除去する性能を有しているかについての確認はいたしておりません。
 浄水器の性能について、皆さまに過度なご期待をいただくような回答をいたしましたことをおわび申しあげます。

まぁ実証データは無いけど活性炭でもある程度期待できるなら、活性炭+逆浸透膜ならもっと期待できるかなーと思ってさっきクリンスイをぽちしてみました。

と言うわけで このツイート に釣られてまんまと買ってしまったのであった。


念のため蛇足ですけど、効果のほどがあるかどうかは僕は当然分かりませんよ。さらに言えば自宅はアクアクララ使ってるんで飲料水には困ってないです。