<?xml version="1.0" encoding="UTF-8"?>

<rdf:RDF
    xmlns="http://purl.org/rss/1.0/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:admin="http://webns.net/mvcb/"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:cc="http://web.resource.org/cc/"
    xml:lang="ja">
<channel rdf:about="http://e8y.net/mag/">
    <title>今日のCPANモジュール</title>
    <link>http://e8y.net/mag/</link>
    <description></description>
    <dc:language>ja</dc:language>
    <dc:creator></dc:creator>
    <dc:date>2008-06-11T16:35:23+09:00</dc:date>
    <admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=3.37" />
    
    <items>
        <rdf:Seq>        <rdf:li rdf:resource="http://e8y.net/mag/015-encode/" />
                <rdf:li rdf:resource="http://e8y.net/mag/014-data-dumper/" />
                <rdf:li rdf:resource="http://e8y.net/mag/013-web-scraper/" />
                <rdf:li rdf:resource="http://e8y.net/mag/012-imager/" />
                <rdf:li rdf:resource="http://e8y.net/mag/011-dbix-class/" />
                <rdf:li rdf:resource="http://e8y.net/mag/010-acme-bleach/" />
                <rdf:li rdf:resource="http://e8y.net/mag/009-dbix-simple/" />
                <rdf:li rdf:resource="http://e8y.net/mag/008-template/" />
                <rdf:li rdf:resource="http://e8y.net/mag/007-www-mechanize/" />
                <rdf:li rdf:resource="http://e8y.net/mag/006-cpan-mini/" />
                <rdf:li rdf:resource="http://e8y.net/mag/005-module-corelist/" />
                <rdf:li rdf:resource="http://e8y.net/mag/004-app-options/" />
                <rdf:li rdf:resource="http://e8y.net/mag/003-fatal/" />
                <rdf:li rdf:resource="http://e8y.net/mag/002-strict/" />
                <rdf:li rdf:resource="http://e8y.net/mag/001-cpan/" />
        </rdf:Seq>
    </items>
</channel>
<item rdf:about="http://e8y.net/mag/015-encode/">
    <title>use Encode;</title>
    <link>http://e8y.net/mag/015-encode/</link>
    <description>日本語／フラグ周りでつまづくのはありがちなので落ち込む必要はないです。この連載も「そろそろ日本語の話題か・・」と思ったのですが、まとめるのがめんどうでテラ放置してました。 すでにたくさんの資料が出回っていることを踏まえ違う切り口でまとめてみます（少々乱暴な部分もあるので、後で ADVANCED も見て下さい）。 まず、以下はそれぞれだいたい同じものと考えていいです。 A： 文字列、 ユニコード（Unicode）、 utf8フラグ付き、 wide character、 decode()されたもの、 &quot;x{3042}&quot; 表記、 use utf8;されたスコープに UTF-8 で書かれた &apos;あ&apos; B...</description>
    <content:encoded><![CDATA[<p>日本語／フラグ周りでつまづくのはありがちなので落ち込む必要はないです。この連載も「そろそろ日本語の話題か・・」と思ったのですが、まとめるのがめんどうでテラ放置してました。</p>

<p>すでにたくさんの資料が出回っていることを踏まえ違う切り口でまとめてみます（少々乱暴な部分もあるので、後で <a href="#ADVANCED">ADVANCED</a> も見て下さい）。</p>

<p>まず、以下はそれぞれだいたい同じものと考えていいです。</p>

<ul>
<li><em>A：</em> 文字列、 ユニコード（Unicode）、 utf8フラグ付き、 wide character、 <code>decode()</code>されたもの、 <code>"x{3042}"</code> 表記、 <code>use utf8;</code>されたスコープに <code>UTF-8</code> で書かれた <code>'あ'</code></li>
<li><em>B：</em> バイト列、 バイトストリーム、 オクテット、 フラグなし、 普通に書かれた（もしくは <code>use bytes;</code> スコープでの）<code>'あ'</code></li>
</ul>

<p>混同しやすいのは、上記 A 郡と「<code>UTF-8</code>」が別物という点です。<code>UTF-8</code> とは <code>Shift_JIS</code> や <code>EUC-JP</code> と同じ、バイトの並び順の仕様（エンコーディング）で、Unicode を表す方法の一つです。</p>

<p>Perl は Unicode を保持する際内部で付けているフラグを（<code>UTF-8</code> を使っているため）「utf8」フラグと呼んでおり、一般向けの説明でもその表現なので少々ややこしいです。</p>

<h3>文字処理の基本</h3>

<p><a href="http://search.cpan.org/perldoc?Encode">Encode</a> の <code>decode()/encode()</code> を使います。</p>

<pre><code>use Encode;

# 入力はバイト列。以下は例で、euc-jp エンコーディングでの「ああ」 
my $input = "xa4xa2xa4xa2";

warn length $text; # =&gt; 4 (バイト長。2バイト×2文字で4バイト)

# (1) まず該当エンコーディングで decode() する
my $text = decode('euc-jp', $input);

# (2) Unicode になったものを文字として好きに処理する
warn length $text; # =&gt; 2 (文字長。2文字)

# (3) 外部へは好きなエンコーディングで encode() して出す
print encode('utf-8', $text); # =&gt; xe3x81x82xe3x81x82
</code></pre>

<p>上記例の <code>$input</code> と <code>$text</code> は意味的には同じ「ああ」ですが、前者はバイト列・後者は文字列です。最後 <code>print()</code> で出す時にまたバイト列にしています。</p>

<p>たとえ入力が <code>UTF-8</code> な文字だったとしても、そのままでは「<code>UTF-8</code> で並んだバイト列」にすぎませんので、<code>decode('utf-8', $input);</code> して Unicode にする必要があります。</p>

<h3>よくある入出力</h3>

<p>具体的な入出力の場面でどう <code>decode()/encode()</code> するのか見てみます。</p>

<h4>ファイル読み書き</h4>

<pre><code>use Encode;
open(my $fh, '&lt;', 'text.txt') or die $!;
while (&lt;$fh&gt;) {
    my $line = decode('euc-jp', $_); # text.txt は euc-jp の場合
    $line =~ s/^s*//; # とかなんとか
    print encode('utf-8', $line); # 例えば utf-8 で出力
}
</code></pre>

<h4>CGI.pm</h4>

<pre><code>#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use Encode;
use utf8;

my $cgi = CGI-&gt;new;

# charset=Shift_JIS な HTML からのフォーム送信を想定
my $name = decode('cp932', $cgi-&gt;param('name')); # 入力を decode()

if ($name eq 'とみた') { # この cgi スクリプト自体は utf-8 で保存すること
    die "「とみた」は私です";
}

my $message = "$nameさん こんちは";

print $cgi-&gt;header('-charset' =&gt; 'Shift_JIS');
print encode('cp932', $message); # ブラウザに返すものは encode()
</code></pre>

<h4>Catalyst</h4>

<p><a href="http://search.cpan.org/perldoc?Catalyst::Plugin::Unicode::Encoding">C::P::Unicode::Encoding</a> を使うと、入力（<code>$c-&gt;req-&gt;params</code>）の <code>decode()</code>、最終出力（<code>$c-&gt;res-&gt;body</code>）の <code>encode()</code> を config で指定したエンコーディングで自動にやってくれます。</p>

<pre><code>use Catalyst qw(
    ConfigLoader
    ...
    Unicode::Encoding
);

__PACKAGE__-&gt;config(encoding =&gt; 'euc-jp');
</code></pre>

<p><code>decode()/encode()</code> 専業ですので、必要に応じて <code>Content-Type</code> ヘッダを指定する必要もあります。特に <a href="http://search.cpan.org/perldoc?Catalyst::Action::RenderView">RenderView</a> を使ってる場合は指定しないとデフォルトの <code>'text/html; charset=utf-8'</code> になるので必須です。</p>

<pre><code>$c-&gt;res-&gt;content_type('text/html; charset=EUC-JP');
</code></pre>

<h4>DBIx::Class</h4>

<p><a href="http://search.cpan.org/perldoc?DBIx::Class::UTF8Columns">DBIx::Class::UTF8Columns</a> を使って ResultSource のクラスで</p>

<pre><code>__PACKAGE__-&gt;utf8_columns(qw( name kana ));
</code></pre>

<p>とか指定すると、そのフィールドへの出し入れの際に自動で <code>decode()/encode()</code> してくれます。使われるエンコーディング（つまり DB の文字コード）は <code>UTF-8</code> 前提です。それ以外の場合は自分で inflate/deflate を書くです。</p>

<h4>Template-Toolkit</h4>

<p>POD に明記されていないので要確認なのですが、<code>UNICODE</code> と <code>ENCODING</code> を指定することで、TT にテンプレートファイルを <code>decode()</code> して読むよう指示できます。</p>

<pre><code>use Template;

my $tt = Template-&gt;new({
    UNICODE  =&gt; 1,       # テンプレートファイルを Unicode として扱う宣言
    ENCODING =&gt; 'utf-8', # テンプレートの文字コード。これで decode() される
});
</code></pre>

<p>もしくは <a href="http://search.cpan.org/perldoc?Template::Provider::Encoding">Template::Provider::Encoding</a> を使い、以下のようにもできます。この場合 Template::Provider::Encoding の他の機能も使うことができます。</p>

<pre><code>use Template;
use Template::Provider::Encoding;

my $tt = Template-&gt;new({
    LOAD_TEMPLATES   =&gt; [ Template::Provider::Encoding-&gt;new ],
    DEFAULT_ENCODING =&gt; 'utf-8', 
});
</code></pre>

<p><code>$tt-&gt;process()</code> の結果は Unicode のままですので、出力する時には以下のように <code>encode()</code> します。（<code>process()</code> の <a href="http://search.cpan.org/perldoc?Template#process($template,_\%vars,_$output,_%options">binmode オプション</a>)や <code>$Template::BINMODE</code> を使うことも可能）</p>

<pre><code># 上の続き

use utf8;
my $vars = { name =&gt; "とみた" }; # 変数は Unicode

$tt-&gt;process('template.tt', $vars, my $text) # $text に入れて
    or die $tt-&gt;error;

print encode('euc-jp', $text); # 出す時に encode()
</code></pre>

<h4>その他のモジュールと Unicode</h4>

<p>最近は Unicode を渡し Unicode を受け取るモジュールがほとんどであり、そうでないものも移行しつつあります。ですので、今でも文字をむりやり全部バイトのまま扱うことも可能ですが、Unicode で扱ったほうが何かと楽になってきました。</p>

<p>各モジュールの Unicode 受け入れ体制についてはそれぞれの POD や Changes をチェックして欲しいのですが、少なくとも今後この連載で取り上げるモジュールについては日本語まわりの話題に触れるようかと。</p>

<h3>Unicode を表記する</h3>

<p>上の例ですでに使っていますが、<code>use utf8;</code> するとそのスコープ（レキシカル）において、<code>UTF-8</code> で書いたリテラルがそのまま Unicode として扱われます。これ以外にも Unicode を表記する方法がいくつかあります。以下の例はどれもだいたい同義で最終的に <code>$text</code> は Unicode です。</p>

<pre><code># A: utf8 プラグマのスコープ内に utf-8 で書く
use utf8;
my $text = "笑"; # この時点でもう Unicode（ソースは UTF-8 で保存する）

# B: utf-8 で書いて decode()
use Encode;
my $text = "笑"; # この時点ではバイト（ソースは UTF-8 で保存した場合）
   $text = decode('utf-8', $text); # ここで Unicode

# C: xHHxHH 表記で書いて decode()
use Encode;
my $text = decode('euc-jp', "xbexd0"); # バイト部分は笑の euc-jp 表現

# D: B の UTF-8 版. perl にとってはほぼ B と同義
use Encode;
my $text = decode('utf-8', "xe7xacx91"); # バイト部分は笑の utf-8 表現

# E: x{UUUU} 表記. UUUU は 16進表記の Unicode コードポイント
my $text = "x{7B11}";

# F: chr() に Unicode コードポイントの10進を渡す
my $text = chr 31505;  # または、
my $text = chr 0x7B11; # コードポイントは16進表記が多いので 0x 表記が楽かも
</code></pre>

<p>特定の文字の Unicode コードポイントや、いろんなエンコーディングでどう表現されるかは <a href="http://www.fileformat.info/info/unicode/char/search.htm">Unicode Character Search</a> が超便利です。（例： <a href="http://www.fileformat.info/info/unicode/char/7b11/index.htm">「笑」のページ</a> や More.. からたどる <a href="http://www.fileformat.info/info/unicode/char/7b11/charset_support.htm">各種エンコーディングでの表記</a>）。最近落ちてることが多くて悲しいです。</p>

<p>Unicode を <a href="http://e8y.net/mag/014-data-dumper/">Data::Dumper</a> した場合、E の <code>"x{UUUU}"</code> 表現になりバイト列と区別が付きます。（<a href="#ADVANCED">ADVANCED</a> も見てください）</p>

<h3>正規表現</h3>

<p>Perl は Unicode サポートを実直に実装しており、正規表現もサポートしています。具体的には、Unicode に対しては <code>.</code> が「1文字」に対応します。これは良いですが、<code>s</code> や <code>d</code> や <code>w</code> なども意味的なマッチになるので要注意です。</p>

<pre><code>use utf8;
if ("あ１2　 " =~ /^(.)(d+)(s+)$/) {
    warn $1; # あ
    warn $2; # １2   // 全角半角問わず数字にマッチ
    warn $3; # "　 " // 全角半角問わず空白にマッチ
}
</code></pre>

<p>半角スペースや数字のみにマッチさせたい場合、やり方はいろいろありますが</p>

<ol>
<li>事前に <a href="http://search.cpan.org/perldoc?Unicode::Normalize">Unicode::Normalize</a>、<a href="http://search.cpan.org/perldoc?Encode::JP::H2Z">Encode::JP::H2Z</a>、<code>tr///</code> などで半角にしておく。</li>
<li>正規表現の部分だけ（<code>use utf8;</code> の逆である）<a href="http://search.cpan.org/perldoc?bytes"><code>use bytes;</code></a> を使う</li>
<li><code>s</code> の代わりに <em><code>[ ]</code></em>、<code>d</code> の代わりに <em><code>[0-9]</code></em> を使う</li>
</ol>

<p>3番でいいと思います。</p>

<h3>文字化け・エラー</h3>

<h4>「化けました」（<code>ãããã</code> みたいなアクセント付きアルファベット多数散見）</h4>

<p>フラグ付きのものとそうでないものをくっつけるとこう化けます。よく TT を、上で示した方法を取らずに使い、テンプレートファイルと挿入する変数のどちらかがバイト列のまま（＝ <code>decode()</code> 忘れ）だったりとかで起こります。</p>

<h4>「Wide character in print ...」</h4>

<pre><code>print "x{7B11}";
</code></pre>

<p>フラグ付きのまま <code>print()</code> すると出ます（＝ <code>encode()</code> 忘れ）。この際、文字そのものは <code>UTF-8</code> で出てくるので読めちゃうかもしれませんが、<code>print()</code> 前に <code>encode()</code> すべきです。ちなみに <code>warn()</code> だとこの warning は出ないですので warning を当てにしている場合は注意です。</p>

<h4>「機種依存文字が出ません」／「波ダッシュが出ません」</h4>

<p><code>'shift_jis'</code> ではなく <code>'cp932'</code> で <code>decode()/encode()</code> するようにすればたいていうまくやってくれます。</p>

<h4>「?」になる</h4>

<p>ある Unicode を <code>encode()</code> した時、指定したエンコーディングでは対応する文字がないよ、という場合、デフォルトでは <code>?</code> になります。この動作を、<code>encode()</code> の第三引数で変更してやることができます。（<a href="http://search.cpan.org/perldoc?Encode#Handling_Malformed_Data">詳細</a>）</p>

<pre><code>print encode('shift_jis', "x{3231}"); # =&gt; ? (株) が Shift_JIS にないので
print encode('shift_jis', "x{3231}", Encode::FB_HTMLCREF); # =&gt; &amp;#12849;
print encode('shift_jis', "x{3231}", Encode::FB_XMLCREF);  # =&gt; &amp;#x3231;
print encode('shift_jis', "x{3231}", Encode::FB_PERLQQ);   # =&gt; x{3231}
</code></pre>

<p>なおブラウザは10進の文字参照（<code>Encode::FB_HTMLCREF</code>）もしくは16進の文字参照（<code>Encode::FB_XMLCREF</code>）でそのまま見えたりしますので使えます（10進の方がより安全と記憶）。</p>

<h3>Encode のその他の機能</h3>

<h4>エンコーディング名の表記ゆれ</h4>

<p>Encode は<a href="http://search.cpan.org/perldoc?Encode::Supported">たくさんのエンコーディングを知っています</a>。<a href="http://search.cpan.org/perldoc?Encode::JP">Encode::JP</a> あたりに日本語で使いそうなエンコーディングが書いてあります。表にあるようにエンコーディング名は表記ゆれをある程度吸収してくれます。（<code>euc-jp</code> の場合 <code>EUC-JP</code> でも <code>ujis</code> でも OK）</p>

<h4>Encode::Encoding オブジェクト</h4>

<p><code>Encode::find_encoding()</code> で、あるエンコーディング名がサポートされているかのチェック、そしてサポートされている場合は <a href="http://search.cpan.org/perldoc?Encode::Encoding">Encode::Encoding</a> オブジェクトを取得できます。</p>

<pre><code>my $encoding = Encode::find_encoding('cp932')
    or die "non supported";

my $text = $encoding-&gt;encode($input); # encode('cp932', $input); と同じ
my $out  = $encoding-&gt;decode($text);  # decode('cp932', $text); と同じ
</code></pre>

<h4>機能というわけじゃないですが</h4>

<p>Encode 以外で <code>decode()/encode()</code> というサブルーチンを持つモジュールがけっこうあるので、<code>Encode::decode()/Encode::encode()</code> と書く習慣を付けてると問題が防げるかもしれません。 </p>

<h3>SEE ALSO</h3>

<p><a href="http://perldoc.perl.org/perlunitut.html">perlunitute</a>（<a href="http://www.r-definition.com/program/perl/perlunitut.htm">和訳</a>）, <a href="http://perldoc.perl.org/perluniintro.html">perlunicode</a>（<a href="http://perldoc.jp/docs/perl/5.8.1/perluniintro.pod">和訳</a>）, <a href="http://perldoc.perl.org/perlunicode.html">perlunicode</a>, <a href="http://search.cpan.org/perldoc?Encode">Encode</a>（<a href="http://digit.que.ne.jp/work/wiki.cgi?Encode">和訳</a>）</p>

<p><a href="http://search.cpan.org/perldoc?Unicode::Japanese">Unicode::Japanese</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2008-06-11T16:35:23+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/014-data-dumper/">
    <title>use Data::Dumper;</title>
    <link>http://e8y.net/mag/014-data-dumper/</link>
    <description><![CDATA[今回は相当基本に立ち返り、Data::Dumper です。すでに説明なく何度も使ってる気もしますが、取り上げておくことに意味があると思うので、やります。 Data::Dumper はある変数のデータ構造を Perl のシンタックスで表現してくれるもので、デバッグ時など普通によく使います。Ruby の p() や .inspect()、JavaScript（Firefox）の .toSource() 相当のものです。Perl5 ではこれがモジュールでの提供です（コア・モジュールです）。 use Data::Dumper; my $data = {     name =&gt; 'Ultra Se...]]></description>
    <content:encoded><![CDATA[<p>今回は<em>相当</em>基本に立ち返り、<a href="http://search.cpan.org/perldoc?Data::Dumper">Data::Dumper</a> です。すでに説明なく何度も使ってる気もしますが、取り上げておくことに意味があると思うので、やります。</p>

<p>Data::Dumper はある変数の<em>データ構造を Perl のシンタックスで表現</em>してくれるもので、デバッグ時など普通によく使います。Ruby の <code>p()</code> や <code>.inspect()</code>、JavaScript（Firefox）の <code>.toSource()</code> 相当のものです。Perl5 ではこれがモジュールでの提供です（コア・モジュールです）。</p>

<pre><code>use Data::Dumper;

my $data = {
    name =&gt; 'Ultra Seven',
    human =&gt; 'Dan Moroboshi',
    transform =&gt; 'glasses',
    power =&gt; ['Emerium Beam', 'Eye Slugger', 'Wide Shot'],
};

warn Dumper $data;

# 出力 ---

$VAR1 = {
          'human' =&gt; 'Dan Moroboshi',
          'transform' =&gt; 'glasses',
          'power' =&gt; [
                       'Emerium Beam',
                       'Eye Slugger',
                       'Wide Shot'
                     ],
          'name' =&gt; 'Ultra Seven'
        };
</code></pre>

<p>Dumper にはいくつも引数を渡すことができます。ハッシュやリストを渡す時は、ばらばらになってしまわないよう <code>\%table</code> や <code>@list</code> のようにリファレンスで渡すと良いです。</p>

<h3>カスタマイズ</h3>

<p>最初の <code>$VAR数字 =</code> 部分は、複数の変数の結果を eval する時にいいのかもしれませんが、たいていは要りません。気になる時やインデントを縮めたいとかいう場合は以下のように指定します。</p>

<pre><code>use Data::Dumper;

local $Data::Dumper::Sortkeys = 1; # ハッシュのキーをソートする
local $Data::Dumper::Indent = 1; # インデントを縮める
local $Data::Dumper::Terse = 1; # $VAR数字要らない

warn Dumper $data;

# 出力結果 ---
{
  'human' =&gt; 'Dan Moroboshi',
  'name' =&gt; 'Ultra Seven',
  'power' =&gt; [
    'Emerium Beam',
    'Eye Slugger',
    'Wide Shot'
  ],
  'transform' =&gt; 'glasses'
}
</code></pre>

<p><a href="http://search.cpan.org/perldoc?Data::Dumper#Configuration_Variables_or_Methods">他のオプションはこちらに</a>あります。</p>

<h3>オブジェクト・サブルーチン</h3>

<p>Dumper した結果は eval して戻せるので、ファイルに書き出しておき do のファイル名構文で <code>my $data = do 'ultra-seven.pl';</code> みたいにして復元できます。</p>

<p>オブジェクトやサブルーチンをシリアライズしたいことはあまりないと思いますが、オブジェクトはデフォルトでは</p>

<pre><code>'wikipedia' =&gt; bless( do{(my $o = 'http://en.wikipedia.org/wiki/Ultra_Seven')}, 'URI::http' ),
</code></pre>

<p>といった感じに bless で表現されるので、モノによっては復元できます。</p>

<p>ただしサブルーチンについては <code>sub { "DUMMY" }</code> と出力され、そこにサブルーチンがあったことがわかるだけです。あまり必要ないでしょうがどうしても出したければ <code>$Data::Dumper::Deparse = 1;</code> を使うことができます。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?Data::Dumper">Data::Dumper</a>, <a href="http://fleur.hio.jp/perldoc/mix/lib/Data/Dumper.ja.html">和訳</a></p>

<p><code>use Data::Dumper; warn Dumper</code> と打つのがめんどいので、たいていエディタにマクロを仕込んだりしてますが、<a href="http://search.cpan.org/~ingy/XXX/lib/XXX.pm">XXX</a> とか <a href="http://search.cpan.org/perldoc?Smart::Comments">Smart::Comments</a> というのを使うのもアリです。</p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2008-01-31T22:57:51+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/013-web-scraper/">
    <title>use Web::Scraper;</title>
    <link>http://e8y.net/mag/013-web-scraper/</link>
    <description>年の瀬にさりげなく再開。 久しぶりということでネタはたくさんあるのですが、ぱっとすぐ思いつくおススメ Web::Scraper を紹介。これはその名のとおり、ウェブのスクレイピング（HTML のある部分を抽出）用のモジュールです。半年くらい前に生まれた新しいモジュールでありながら、すでにこの分野でメジャー感がある miyagawa プロダクトです。 API が用意されているサイトの情報は普通に API で取ればよいですが、世の中そうばかりでもないわけで、HTML を文字列処理したりするわけです。昔からこの辺は Perl が得意としてきたところですが、Web::Scraper がどう新しくて便利...</description>
    <content:encoded><![CDATA[<p>年の瀬にさりげなく再開。</p>

<p>久しぶりということでネタはたくさんあるのですが、ぱっとすぐ思いつくおススメ <a href="http://search.cpan.org/perldoc?Web::Scraper"><em>Web::Scraper</em></a> を紹介。これはその名のとおり、ウェブの<em>スクレイピング</em>（HTML のある部分を抽出）用のモジュールです。半年くらい前に生まれた新しいモジュールでありながら、すでにこの分野でメジャー感がある miyagawa プロダクトです。</p>

<p>API が用意されているサイトの情報は普通に API で取ればよいですが、世の中そうばかりでもないわけで、HTML を文字列処理したりするわけです。昔からこの辺は Perl が得意としてきたところですが、Web::Scraper がどう新しくて便利なのかは、<a href="http://www.slideshare.net/miyagawa/web-scraper-shibuyapm-tech-talk-8">作者によるプレゼン資料</a>にわかりやすく説明されているとおりです。</p>

<ul>
<li>正規表現ではなく <em>CSS のシンタックス</em>（や XPath）で切り出し場所を特定できる</li>
<li>トライ＆エラーに便利な<em>コマンドラインインターフェース</em>が付属</li>
<li>文字コードや URL の正規化など裏側処理を Web::Scraper がワンモジュールでめんどうみてくれるので、<em>コードがすっきり</em></li>
</ul>

<p>素敵、というわけでさっそく</p>

<h3>使い方</h3>

<p>Amazon の商品ページから価格部分を取るサンプルで説明してみます。</p>

<p><img src="http://e8y.net/mag/013-web-scraper/amazon.jpg" /></p>

<pre><code>use Web::Scraper;
use URI;

# 価格部分を yen という名前で取るスクレイパーを作成
my $scraper = scraper {
    process '#buyboxTable b.price', 'yen' =&gt; 'TEXT';
};

# 悪魔の箱ページのURLオブジェクトを、
my $uri = new URI('http://www.amazon.co.jp/o/ASIN/B000WQKBE2/');

# 先ほどのスクレイパーに渡す。（スクレイピングされる）
my $res = $scraper-&gt;scrape($uri);

print $res-&gt;{yen}; # ￥ 4,401
</code></pre>

<p>Web::Scraper は、use すると <code>scraper</code> という関数をエクスポートします。<code>scraper</code> は、サンプルのようにスクレイピングの指示をブロック（<code>{ }</code>）の形で取り、<em>スクレイパー</em>オブジェクトを返します。そのスクレイパーは <code>scrape()</code> という関数を持ち、それに URL とか渡すとスクレイピングして結果を返してくれます。</p>

<h3>解説</h3>

<p>scraper に渡すブロックの中の構文は以下のようになります。</p>

<pre><code>process どこから, 何というキー名で =&gt; どう取得（値の形式）;
</code></pre>

<p>先ほどのサンプルだと、<code>'#buyboxTable .price'</code> という箇所から、<code>yen</code> という名前でその <code>'TEXT'</code> を取る、みたいに読めます。</p>

<h4>1. どこから</h4>

<p>ここには HTML から切り出す場所を CSS セレクタもしくは <a href="http://ja.wikipedia.org/wiki/XPath">XPath</a> で記述します。Amazon の価格部分は <code>id="buyboxTable"</code> の中にある <code>&lt;b class="price"&gt;</code> だったので <code>'#buyboxTable b.price'</code> と指定しています。</p>

<p>もちろん XPath で <code>'//table[ @id="buyboxTable" ]//b[ @class="price"]'</code> みたいな感じでも OK ですが、この場合は CSS セレクタの方がわかりやすい。XPath はひどいマークアップの HTML から何かを取りたい時とかに本領発揮します。</p>

<h4>2. キー名</h4>

<p>scraper が取るブロックには、そのページで取りたい箇所の分 process 行を並べることができますが、それぞれの結果に付けるキー名を指定します。</p>

<pre><code>my $scraper = scraper {
    process '#buyboxTable .price', 'yen' =&gt; 'TEXT';
    process '#primaryUsedAndNew .price', 'used' =&gt; 'TEXT';
    process '//*[ @id="ftMessage" ]//b', 'delivery' =&gt; 'TEXT';
};
</code></pre>

<p>これで、<code>$scraper-&gt;scrape($uri)</code> の結果は以下のようになります（utf8 フラグ付き）。</p>

<pre><code>{
    yen =&gt; "￥ 4,401",
    used =&gt; "￥ 3,639",
    delivery =&gt; "2007/12/28 金曜日 にお届けします！",
}
</code></pre>

<p>ちなみに process の仲間に result というのがあって、これでキー名を指定しておくとハッシュじゃなくてそのものが返ってきます。詳しくは後述の実例のリンク先で見てください。</p>

<p>セレクタの指定によっては合致する部分が複数ある場合がありますが、キー名を <code>'item[]'</code> のように各カッコ付きで指定することで、リストで取得することもできます。</p>

<pre><code># 全 &lt;a&gt; タグの href 属性を url というキーにリストで
my $res = scraper { process 'a', 'url[]' =&gt; '@href'; }-&gt;scrape($uri);

use YAML;
print Dump $res;

# 結果
---
url:
  - !!perl/scalar:URI::http http://www.amazon.co.jp/ref=bd_vg/250-9239974-3346614
  - !!perl/scalar:URI::http http://www.amazon.co.jp/gp/cart/view.html/ref=topnav__vg/250-9239974-3346614
  - !!perl/scalar:URI::http http://www.amazon.co.jp/gp/registry/wishlist/ref=topnav__vg/250-9239974-3346614
...
</code></pre>

<p>※ <a href="http://search.cpan.org/perldoc?URI">URI</a> モジュールはそのうち取り上げます。</p>

<h4>3. 値の形式</h4>

<p><code>'TEXT'</code> や <code>'@href'</code> が出てきましたが、値の取り方をいろいろな方法で指定できます。ここが柔軟で、いろいろ工夫のしがいがあるところです。</p>

<p>まずは基本。http://example.com/ が</p>

<pre><code>&lt;div&gt;
    &lt;a href="/2008.html" target="_blank"&gt;Happy New Year&lt;/a&gt;!
&lt;/div&gt;
</code></pre>

<p>という HTML だったとすると以下のようになります。</p>

<ul>
<li><em>'HTML'</em> はその部分の内側の HTMLです。 <br />
<code>process 'div', 'test' =&gt; 'HTML';</code> <br />
の結果は <code>'&lt;a href="/2008.html" target="_blank"&gt;Happy New Year&lt;/a&gt;!'</code></li>
<li><em>'TEXT'</em> は HTML タグを取りはらったもの。 <br />
<code>process 'div', 'test' =&gt; 'TEXT';</code> <br />
の結果は <code>'Happy New Year!'</code></li>
<li><em>'@属性名'</em> で属性の値。 <br />
<code>process 'div a', 'test' =&gt; '@target';</code> <br />
の結果は <code>'_blank'</code></li>
</ul>

<p>これ以外の方法で取りたい時用として、</p>

<ul>
<li><em>scraper {}</em> をさらに渡してネストさせる</li>
<li><em>フィルタ</em> という <code>'TEXT'</code> などを手軽に加工する方法が用意されています</li>
<li>さらに <em>サブルーチンを渡す</em>と <code>$_</code> としてその <a href="http://search.cpan.org/perldoc?HTML::Element">HTML::Element</a> が来るので好きにできます。</li>
</ul>

<p>これらについては後述の実例リンク先を参照。</p>

<p>一つの場所から上記を組み合わせて取りたい時は、scraper を渡してネストさせるか、もしくは</p>

<ul>
<li><p><em>ハッシュ</em> でまとめます。</p>

<pre><code>process 'div a', 'link' =&gt; {
    text =&gt; 'TEXT',
    host =&gt; [ '@href', sub { $_-&gt;host } ],
};
</code></pre>

<p>で以下のように取れます。</p>

<pre><code>link =&gt; {
    text =&gt; 'Happy New Year',
    host =&gt; 'example.com',
}
</code></pre></li>
</ul>

<h3>コマンドラインインターフェース</h3>

<p>Web::Scraper をインストールすると scraper というコマンドが入ります。これが超絶便利です。HTML はサイトによってまちまちなのでトライアンドエラーを繰り返しがちですが、いつのまにかスクレイピングに成功するのが目的になってしまってたり。。みたいな事態を防げます。</p>

<pre><code>$ scraper &lt;取るURLまたはhtmlファイルのパス&gt;
</code></pre>

<p>で始めます。 <br />
さっそくミニミニさまーずの放送時間を <a href="http://tv.yahoo.co.jp/bin/search?p=%A5%DF%A5%CB%A5%DF%A5%CB%A4%B5%A4%DE%A4%A1%A1%C1%A4%BA&amp;cate=0&amp;search222=%B8%A1%BA%F7&amp;area=tokyo">Yahooテレビのこのページ</a>から取ってみることにします。</p>

<pre><code>$ scraper "http://tv.yahoo.co.jp/bin/sea...(長いので省略)"

scraper&gt;
</code></pre>

<p>と、<em>そのページについての scraper シェル</em>が立ち上がります。ここで、おもむろに process 文を作っていくのですが、実際の対象の HTML はいつでも</p>

<pre><code>scraper&gt; s
</code></pre>

<p>と、s コマンドでソースを見ることができます。ただし、scraper + <a href="http://www.getfirebug.com/jp.html">Firebug</a> で鬼に金棒です。</p>

<p><img src="http://e8y.net/mag/013-web-scraper/yahootv.jpg" /></p>

<p>Firebug からコピーした XPath を使って process 文を作っていきます。scraper シェルの中だけ 「何というキー名で => どう取得（値の形式）」の代わりに WARN というのが使えます。これはその場ですぐ結果を見ることができるものです。</p>

<pre><code>scraper&gt; process '/html/body/center/table[6]/tbody/tr[2]/td[2]/small', WARN;
</code></pre>

<p>何も起きません。実は Firebug で取った table タグ内の XPath は Firefox がレンダリング時に加えた実際の HTML にはない tbody タグが入っているので、それを取ります。</p>

<pre><code>scraper&gt; process '/html/body/center/table[6]/tr[2]/td[2]/small', WARN;
&lt;small&gt;20:54〜21:00&lt;/small&gt;
</code></pre>

<p>これでうまく出ました。他のを全部取ってみるよう tr の指定を取ります。こういった微調整＆確認がすぐできるのが scraper シェルのすばらしいところ。</p>

<pre><code>scraper&gt; process '/html/body/center/table[6]/tr/td[2]/small', WARN;
&lt;small&gt;20:54〜21:00&lt;/small&gt;
&lt;small&gt;26:25〜26:30&lt;/small&gt;
&lt;small&gt;17:54〜18:00&lt;/small&gt;
...
</code></pre>

<p>うまくいったので、WARN を <code>'list[]' =&gt; 'TEXT';</code> に変えます。変えた後は、y コマンドで、YAML::Dump した結果を表示できます。</p>

<pre><code>scraper&gt; process '/html/body/center/table[6]/tr/td[2]/small', 'list[]' =&gt; 'TEXT';
scraper&gt; y
---
list:
  - 20:54〜21:00
  - 26:25〜26:30
  - 17:54〜18:00
...
</code></pre>

<p>最後に、c でコードを吐き出してくれます。試行錯誤した process 文を全部出したい場合は c all です。</p>

<pre><code>scraper&gt; c
#!/usr/bin/perl
use strict;
use Web::Scraper;
use URI;

my $uri = URI-&gt;new("http://tv.yahoo.co.jp/bin/search?p=%A5%DF%A5%CB%A5%DF%A5%CB%A4%B5%A4%DE%A4%A1%A1%C1%A4%BA&amp;cate=0&amp;search222=%B8%A1%BA%F7&amp;area=tokyo");
my $scraper = scraper {
    process '/html/body/center/table[6]/tr/td[2]/small', 'list[]' =&gt; 'TEXT';
};
my $result = $scraper-&gt;scrape($uri);
</code></pre>

<p>まあこれこの年末しか使えないし、ブラウザで表示している時点で目的は達成されている気がしますが、まあサンプルということで（笑）</p>

<h3>TIPS</h3>

<p><em>UserAgent を変える</em></p>

<pre><code>use LWP::UserAgent;
my $ua = new LWP::UserAgent( agent =&gt; 'Mozilla/5.0 ...' );

# セット
$scraper-&gt;user_agent($ua);

# その UA でスクレイピング
print Dumper $scraper-&gt;scrape($url);
</code></pre>

<p><em>Basic 認証</em></p>

<pre><code># 普通にこの方法が楽
my $url = new URI('http://user:pass@example.com/private/');
</code></pre>

<p><em>ログイン認証</em></p>

<p><code>$scraper-&gt;scrape()</code> には URI オブジェクト以外に、HTML そのものを文字列で渡すこともできます。なので、普通に Mech とかで進んで、コンテンツを Web::Scraper に渡すとよいです。</p>

<pre><code>use WWW::Mechanize;
my $mech = new WWW::Mechanize;

# mech で進んで...（ニコニコ動画の）
$mech-&gt;get('http://www.nicovideo.jp/ranking/view/daily/all');
$mech-&gt;submit_form(
    fields =&gt; {
      mail =&gt; 'me@example.jp',
      password =&gt; 'p4ssw0rd',
    },
);

# ランキングを取るスクレイパーに
my $scraper = scraper {
    process 'a.video', 'ranking[]' =&gt; '@href';
};

# mech から HTMLを渡してスクレイプさせる
my $res = $scraper-&gt;scrape($mech-&gt;content);
</code></pre>

<p>HTML 渡しの場合スクレイパーはそれが何という URL のものなのかわかりませんが、 Web::Scraper にある URL の正規化機能を生かすには、<code>scrape()</code> の第二引数で渡せばよいので、mech からの場合は以下のようにすると良いです。</p>

<pre><code>my $res = $scraper-&gt;scrape($mech-&gt;content, $mech-&gt;uri);
</code></pre>

<h3>実例</h3>

<ul>
<li>Web::Scraperの <a href="http://svn.bulknews.net/repos/public/Web-Scraper/trunk/eg">例ディレクトリ</a> や <a href="http://svn.bulknews.net/repos/public/Web-Scraper/trunk/t">テストスクリプト</a></li>
<li><a href="http://b.hatena.ne.jp/t/webscraper?sort=eid">はてなブックマーク - タグ webscraper</a></li>
<li><a href="http://coderepos.org/share/browser/lang/perl/Encode-JP-Mobile/trunk/tools">Encode::JP::Mobile の tools ディレクトリ</a>には、各キャリアの絵文字コードのウェブページをスクレイピングするスクリプトがあります。</li>
</ul>

<h3>Happy holidays!</h3>

<p>まぐまぐ、半年発行しないでいると廃刊扱いになって<em>バックナンバーごと消えてしまう</em>という仕様らしいのであわてて配送。そういう仕組みだったとは（笑） とはいえリクエストもあったので来年は定期的に書こうと思います。</p>

<p>ではみなさん、よいお年を</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?Web::Scraper">Web::Scraper</a></p>

<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B0011U0AGW/ele-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/21%2B5BOQDYdL.jpg" alt="内村プロデュース~発酵紀" style="border: none;" /></a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-12-29T22:42:41+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/012-imager/">
    <title>use Imager;</title>
    <link>http://e8y.net/mag/012-imager/</link>
    <description>帰ってきた今日の CPAN。冨田がお気に入りモジュールを趣味で紹介する日刊メールマガジン。というか、日刊であることはもちろん、メルマガやってたことさえ忘れかけていた と言っても過言ではないのだ！？ を、ヨロシクお願いします。 と、時効警察ぽく始めてみたりしました。今日は画像編集用モジュール Imager を説明します。サムネールを作ったり形式を変換したりなどなど画像操作のいろんな要望に応えてくれるモジュールです。 他の画像編集ライブラリ GD や ImageMagick の Perl インターフェースに比べ、できることは多く、必要とする外部ライブラリが少なめで、同じくらい速く、品質も悪くなく、...</description>
    <content:encoded><![CDATA[<p>帰ってきた今日の CPAN。冨田がお気に入りモジュールを趣味で紹介する日刊メールマガジン。というか、日刊であることはもちろん、メルマガやってたことさえ忘れかけていた と言っても過言ではないのだ！？ を、ヨロシクお願いします。</p>

<p>と、時効警察ぽく始めてみたりしました。今日は画像編集用モジュール <a href="http://search.cpan.org/perldoc?Imager"><em>Imager</em></a> を説明します。サムネールを作ったり形式を変換したりなどなど画像操作のいろんな要望に応えてくれるモジュールです。</p>

<p>他の画像編集ライブラリ <a href="http://www.libgd.org/">GD</a> や <a href="http://www.imagemagick.org/">ImageMagick</a> の Perl インターフェースに比べ、できることは多く、必要とする外部ライブラリが少なめで、同じくらい速く、品質も悪くなく、そして<em>API がきれい</em>です。使わない手はありません。</p>

<p>Imager も他の画像編集ライブラリのようにコアは C ですが、コアと Perl インターフェースが別々ではなく、セットで Perl 専用に開発されているという点が強みになっているのだと思います。公開から数年たっていますが、<a href="http://imager.perl.org/svn/trunk/Imager/">Subversion レポジトリ</a>のログを見るとわかりますが今なお開発が活発です。（開発は <a href="http://imager.perl.org/">imager.perl.org</a> ドメインで行なわれています）</p>

<p>どうでもいい点ですが、C ライブラリの Perl binding はメソッドが camelCase になる場合が多いですが、ぼくは <a href="http://perldoc.jp/docs/perl/5.8.0/perlstyle.pod">perlstyle</a> や <a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113008/ele-22/ref=nosim/">PBP</a> で推奨されている non_camelcase の方が好みで、このあたりでも GD などより Imager がお気に入りだったりします。</p>

<h3>インストール</h3>

<p>開発者たちの Good Job に付いていくには cpan で最新版を入れるのがよいかと。ただ、apt や yum とかに Imager そのものがあります。なお、事前に jpeglib libtiff libpng libgif libttf libfreetype あたりのライブラリが入ってるか確認しておくとよいです。なくても Imager は入りますが、対応形式が少なくなってしまいます。Debian の場合だとこんな感じですかね</p>

<pre><code># aptitude install libjpeg-dev libtiff-dev libpng-dev giflib-dev libttf-dev libfreetype6-dev
# cpan Imager
</code></pre>

<p>インストールされた Imager が対応したファイル形式は <code>%Imager::formats</code> ハッシュのキーとして入っていますので、以下のようなワンライナーで対応形式一覧を見れます。</p>

<pre><code>perl -MImager -e 'print join ", ", sort keys %Imager::formats'
</code></pre>

<p>OSX はもちろん Windows もサポートされているのも心強いところです。<a href="http://search.cpan.org/src/TONYC/Imager-0.58/README">README</a> によると ActivePerl と cygwin でテストされているようです。<a href="http://e8y.net/mag/012-imager/sample/">今回のサンプル</a>は Debian、cygwin で同じスクリプトで動作することを確認してます。</p>

<h3>使い方</h3>

<p>使い方は単純で、<code>Imager-&gt;new</code> で Imager のインスタンスを作成した後、それが持つ たくさんの<em>メソッドのいずれか</em>を使って画像操作します。</p>

<h4>サムネール作成</h4>

<p>よくあるサムネール作成をやってみます。</p>

<pre><code>use Imager;

my $img = Imager-&gt;new;

# ある画像を開き...（type を指定しない ＝ 自動認識）
$img-&gt;read( file =&gt; 'nya.png' )
    or die $img-&gt;errstr;

# 縦か横が160pxになるように縮小し...
# （新しい Imager オブジェクトが返るので、それで元のを上書き）
$img = $img-&gt;scale(
    xpixels =&gt; 160,
    ypixels =&gt; 160,
);

# Jpeg、画質 90% で保存
$img-&gt;write( file =&gt; 'nya-scaled.jpg', jpegquality =&gt; 90 )
    or die $img-&gt;errstr;
</code></pre>

<p><a href="http://e8y.net/mag/012-imager/sample/nya.png">この画像が</a> こうなります。 <br />
<a href="http://e8y.net/mag/012-imager/sample/nya-scaled.jpg"><img src="http://e8y.net/mag/012-imager/sample/nya-scaled.jpg" alt=""></a></p>

<p>この例では Imager のメソッドの <a href="http://search.cpan.org/perldoc?Imager::Files#read"><code>read()</code></a>、 <a href="http://search.cpan.org/perldoc?Imager::Transformations#scale"><code>scale()</code></a>、 <a href="http://search.cpan.org/perldoc?Imager::Files#write"><code>write()</code></a> を使ってます。その他のたくさんのメソッドは POD に</p>

<ul>
<li><a href="http://search.cpan.org/perldoc?Imager#METHOD_INDEX">アルファベット順の一覧</a></li>
<li><a href="http://search.cpan.org/perldoc?Imager#CONCEPT_INDEX">「○○をしたい」の逆引き</a> </li>
</ul>

<p>の2系統でまとめれられていて、たいへんわかりやすいです。各リンク先にあるのメソッドの説明も、オプションに何が指定できるのか、何が返ってくるのか、サンプル中心で英語もわかりやすいと思います。</p>

<p>例えば <a href="http://search.cpan.org/perldoc?Imager::Transformations#scale"><code>scale()</code></a> の項目を見ると、200x200に「収まるように」小さくするには、<code>type =&gt; 'min'</code>、縦横比を無視してそのサイズに引き伸ばしたい場合は <code>type =&gt; 'nonprop'</code> というオプションをつければいいことがわかります。</p>

<p>元画像の50%というように指定したい場合は、<a href="http://search.cpan.org/perldoc?Imager#CONCEPT_INDEX">逆引きのところ</a> を「size」で検索すると <code>size, image - "getwidth" in Imager::ImageTypes, "getheight" in Imager::ImageTypes</code> とあり、<code>getwidth()</code> で画像のサイズが取れるようですので、こんな風に。</p>

<pre><code>$img = $img-&gt;scale(
    xpixels =&gt; $img-&gt;getwidth * 0.5,
);
</code></pre>

<p>画像を縮小するときはシャープマスクをかけるときれいです。これも<a href="http://search.cpan.org/perldoc?Imager#CONCEPT_INDEX">逆引きのところ</a> を「sharp」で探してみると以下のようなのが見つかります。</p>

<p><code>sharpen - "unsharpmask" in Imager::Filters, "conv" in Imager::Filters</code> …と、２種類方法があるようですが、アンシャープマスクの方を弱めにかけるには、以下のコードを先ほどの例の <code>$img-&gt;write()</code> の前に入れる感じですね。</p>

<pre><code>$img-&gt;filter( type =&gt; 'unsharpmask', stddev =&gt; 1 )
    or die $img-&gt;errstr;
</code></pre>

<p>こんな感じになりました。 <br />
<a href="http://e8y.net/mag/012-imager/sample/nya-sharpen.jpg"><img src="http://e8y.net/mag/012-imager/sample/nya-sharpen.jpg" alt=""></a></p>

<p>ちなみに、アンシャープマスクは「シャープにしない」という意味ぽい名前ですが、そうじゃなく、ボケた（アンシャープな）画像との差を計算して逆にシャープにするというロジックの名前です。</p>

<h4>図形描画</h4>

<p>図形を描画することもできます。四角を描くには <a href="http://search.cpan.org/perldoc?Imager::Draw#box"><code>box()</code></a> を使って以下のようにします。</p>

<pre><code>$img-&gt;box(
    xmin =&gt;  20, ymin =&gt; 320,
    xmax =&gt; 170, ymax =&gt; 370,
    color =&gt; '#ffffff',
    filled =&gt; 1,
);
</code></pre>

<p>こんな感じの画像ができます。<a href="http://e8y.net/mag/012-imager/sample/12-box.pl">ソース全文</a> <br />
<a href="http://e8y.net/mag/012-imager/sample/nya-box.jpg"><img src="http://e8y.net/mag/012-imager/sample/nya-box.jpg" alt=""></a></p>

<h4>画像の貼り付け</h4>

<p>四角以外に、丸とか、座標を指定してもっと複雑な図形もかけますが、ふきだしを追加したい場合とかならそのような画像を貼り付けるほうが楽です。</p>

<p><a href="http://e8y.net/mag/012-imager/sample/caption.gif">このふきだし画像</a> （背景が透過な GIF）を貼り付けるには、<a href="http://search.cpan.org/perldoc?Imager::Transformations#rubthrough"><code>rubthrough()</code></a> で以下のようにします。</p>

<pre><code># ふきだし画像を透過を考慮して貼り付け...
$img-&gt;rubthrough(
    src  =&gt; do {
        my $tmp = Imager-&gt;new;
        $tmp-&gt;read( file =&gt; 'caption.png' ) or die $tmp-&gt;errstr;
        $tmp; # srcへふきだし画像のImagerオブジェクトを渡す
    },
    tx =&gt; 22,
    ty =&gt; 567,
);
</code></pre>

<p>こんな風になります。透過処理をしない場合は <code>paste()</code> ですが、貼り付けたいのはたいてい透過な部分がある画像なので、結局いつも <code>rubthrough()</code> を使ってます。 <br />
<a href="http://e8y.net/mag/012-imager/sample/nya-paste.jpg"><img src="http://e8y.net/mag/012-imager/sample/nya-paste.jpg" alt=""></a></p>

<h4>テキスト</h4>

<p>こうなってくると そろそろ文字も追加してみたくなるころですので、逆引きのところを調べると、<code>drawing text - "string" in Imager::Draw, "align_string" in Imager::Draw</code>とあります。</p>

<p><a href="http://search.cpan.org/perldoc?Imager::Draw#string"><code>string()</code></a> を見ると、文字については特別で、Imager::Font オブジェクトとの組み合わせになります。全体では以下のようなコードになります。</p>

<pre><code># IPA Pゴシックフォントをオブジェクト化
my $font = Imager::Font-&gt;new( file =&gt; 'ipagp.ttf' );

# 文字を書き込み...
$img-&gt;string(
    x =&gt; 40,
    y =&gt; 650,
    string =&gt; "潜入成功ニャ！",
    utf8 =&gt; 1,
    font =&gt; $font,
    size =&gt; 38,
    aa =&gt; 1,
    color =&gt; '#000000',
);
</code></pre>

<p>こんな風になりました。<a href="http://e8y.net/mag/012-imager/sample/12-caption.pl">全体のコードはこちら</a> <br />
<a href="http://e8y.net/mag/012-imager/sample/nya-caption.jpg"><img src="http://e8y.net/mag/012-imager/sample/nya-caption.jpg" alt=""></a></p>

<p>string パラメータの文字列は、</p>

<ul>
<li>utf8 フラグ付きで渡すか</li>
<li>UTF-8 の文字を utf8 => 1 オプションと一緒に渡してあげる</li>
</ul>

<p>必要があります。このあたりは、メルマガでまだ utf8 まわりを取り上げてないので、詳細は省略します。いずれまとめて説明します。</p>

<p>さて、テキストの入力を考え始めると、</p>

<ul>
<li>字送り</li>
<li>行送り</li>
<li>折り返し処理</li>
<li>縦書き！</li>
</ul>

<p>などのめんどうな話がでてきます。しかし、そこは CPAN。このあたりの文字組み処理は、Imager からの派生モジュールで <a href="http://search.cpan.org/perldoc?Imager::DTP">Imager::DTP</a> というのがあり、これがかなりいい感じにやってくれます。これはまた別の機会に取り上げます。</p>

<p>とはいえ Imager だけでも、デジカメ写真の撮影日とかを EXIF から取りたいよ（→ <a href="http://search.cpan.org/perldoc?Imager::ImageTypes#tags"><code>tags()</code></a> ）とか、モザイク画像にしたいよ（→  <a href="http://search.cpan.org/perldoc?Imager::Filters#mosaic"><code>filter( type =&gt; "mosaic" )</code></a> ）とか、使える機能がいろいろです。一度 <a href="http://search.cpan.org/perldoc?Imager#CONCEPT_INDEX">逆引きのところ</a> を通してながめておくことをおすすめします。</p>

<p>ちなみに今回、予告していた Catalyst じゃなくて Imager を取り上げたのは、今回のをネタに何かウェブアプリをサンプルで作りながら進めようかと思ったからなのですが、どうしようかな。考え中です。次回をお楽しみに。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?Imager">Imager</a>, <a href="http://search.cpan.org/perldoc?Imager::Tutorial">チュートリアル</a>, <a href="http://search.cpan.org/perldoc?Imager::Cookbook">Cookbook</a></p>

<p>実は、CPAN には <a href="http://search.cpan.org/perldoc?Image::Imlib2">Image::Imlib2</a> という、もうひとつ気になる画像編集モジュールがあります。これは、できることは少ないですが、<em>処理速度が超絶速い</em>です。たとえば、単純なサムネールを作るだけみたいな処理で処理速度が求められる場合は、このモジュールも検討するとよいです。ただ、Perl インターフェースはまだ新しくアルファ版といった感じです。</p>

<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B000ROODRU/ele-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/21DT9guGuyL.jpg" alt="帰ってきた時効警察 DVD-BOX" style="border: none;" /></a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-05-24T04:04:12+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/011-dbix-class/">
    <title>use DBIx::Class;</title>
    <link>http://e8y.net/mag/011-dbix-class/</link>
    <description>今回は、前々回 DBIx::Simple を紹介した際に予告した本格 O/R マッパーモジュール DBIx::Class （略称 DBIC）を紹介します。  Perl の世界では、昔から Class::DBI （略称 CDBI）という優れた ORM モジュールがあり、プロダクションでもがりがり使われてきました。CDBI をより便利にする拡張もたくさん現れ、中でも Class::DBI::Sweet というモジュールがよく使われていました。 この CDBI::Sweet の作者が、CDBI の拡張という形ではできないことまでやりたくなってついに一から書き直したのが DBICです。今では多くの開発...</description>
    <content:encoded><![CDATA[<p>今回は、前々回 DBIx::Simple を紹介した際に予告した本格 O/R マッパーモジュール <a href="http://search.cpan.org/perldoc?DBIx::Class"><em>DBIx::Class</em></a> （略称 DBIC）を紹介します。 </p>

<p>Perl の世界では、昔から <a href="http://search.cpan.org/perldoc?Class::DBI">Class::DBI</a> （略称 CDBI）という優れた ORM モジュールがあり、プロダクションでもがりがり使われてきました。CDBI をより便利にする拡張もたくさん現れ、中でも <a href="http://search.cpan.org/perldoc?Class::DBI::Sweet">Class::DBI::Sweet</a> というモジュールがよく使われていました。</p>

<p>この CDBI::Sweet の作者が、CDBI の拡張という形ではできないことまでやりたくなってついに一から書き直したのが DBICです。今では多くの開発者が加わり、（CDBI ほど枯れてませんが）プロダクションで使えるレベルになったと思います。先日の YAPC::Asia でも <a href="http://tokyo2007.yapcasia.org/wiki/?SlidesFromTalks">いくつかセッションが</a> ありました。</p>

<p>CDBI、DBIC 以外の ORM モジュールもありますが、現時点ではこれが一番おすすめできます。<em>現実的</em>（複雑なことも可能・カスタマイズ可能）であり、それらを満たす範囲で十分わかりやすい API。今から Perl 始める人は幸せだなと。</p>

<h3>使い方</h3>

<p>例として、SQLite でまたドラクエの呪文 DB を作ることにします。<a href="http://e8y.net/mag/011-dbix-class/">http://e8y.net/mag/011-dbix-class/</a> の db ディレクトリの中に元ネタの SQL 文 schema.sql があるので、これを流し込んだ SQLite DB ファイル spell.db を作成しておいてください。</p>

<p>DBIC は DBIx::Simple と違い、事前に「データベース」に対応したクラス（<em>スキーマクラス</em>）や、「テーブル」に対応したクラスを用意しておき、プログラムではそいつらを通して DB にアクセスします。この対応クラスを用意するには手動と自動の2種類ありますが、半自動（<em>自動＋手動で微調整</em>がおすすめです。この方法を簡単に解説します。</p>

<h4>スキーマクラス</h4>

<p>プロジェクト名が Magic だった場合、スキーマクラスは Magic::Schema というパッケージ名にする場合が多いです。このファイルから書いていきます。といっても書く量はわずかです。lib/Magic/Schema.pm として以下のようなコードを保存します。</p>

<pre><code>package Magic::Schema;
use strict;
use base qw/DBIx::Class::Schema::Loader/;

__PACKAGE__-&gt;loader_options(
    debug =&gt; 1,
    exclude =&gt; qr/^sqlite_/,
);

1;
</code></pre>

<p><a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader">DBIx::Class::Schema::Loader</a> を継承し、コードは loader_options を指定するくらいです。ちなみに手動の場合は DBIx::Class::Schema::Loader ではなく <a href="http://search.cpan.org/perldoc?DBIx::Class::Schema">DBIx::Class::Schema</a> を継承します。</p>

<h4>プログラムから利用</h4>

<p>こいつを実際にプログラムで使うには、以下のようにします。</p>

<pre><code>use lib 'lib';

# スキーマクラスを use し、
use Magic::Schema;

# スキーマクラスのインスタンスを作成
my $schema = Magic::Schema-&gt;connect('dbi:SQLite:dbname=db/spell.db');

# ResultSet を作成し全レコード取得したり...
my $rs = $schema-&gt;resultset('Spell')-&gt;search;

# 件数を出力したり...
warn $rs-&gt;count, " rows ---
</code></pre>

<p>";</p>

<pre><code># word、descフィールドを出力しながらイテレートしたり...
while (my $row = $rs-&gt;next) {
    warn sprintf "* %s: %s
</code></pre>

<p>", $row->word, $row->desc;
    }</p>

<p>これを test.pl とかで保存して、perl test.pl してみます。</p>

<pre><code>Magic::Schema::ClassMap-&gt;load_components("PK::Auto", "Core");
Magic::Schema::Spell-&gt;load_components("PK::Auto", "Core");
Magic::Schema::ClassMap-&gt;table("class_map");
Magic::Schema::ClassMap-&gt;add_columns(
  "id",
  { data_type =&gt; "INTEGER", is_nullable =&gt; 0, size =&gt; undef },
  "name",
  { data_type =&gt; "VARCHAR", is_nullable =&gt; 0, size =&gt; 255 },
);
Magic::Schema::ClassMap-&gt;set_primary_key("id");
Magic::Schema::Spell-&gt;table("spell");
Magic::Schema::Spell-&gt;add_columns(
  "id",
  { data_type =&gt; "INTEGER", is_nullable =&gt; 0, size =&gt; undef },
  "word",
  { data_type =&gt; "VARCHAR", is_nullable =&gt; 0, size =&gt; 255 },
  "class_id",
  { data_type =&gt; "INTEGER", is_nullable =&gt; 0, size =&gt; undef },
  "desc",
  { data_type =&gt; "VARCHAR", is_nullable =&gt; 0, size =&gt; 255 },
  "ctime",
  { data_type =&gt; "DATETIME", is_nullable =&gt; 0, size =&gt; undef },
);
Magic::Schema::Spell-&gt;set_primary_key("id");

13 rows ---
* メラ: 火の玉
* ギラ: 炎
* イオナズン: 爆発で敵全体を攻撃
* ホイミ: HPを回復する
つづく
</code></pre>

<p>debug を ON にしているので、Loader が DB から取得できる内容を元にテーブルの対応クラスをどう作っていったかがわかります。</p>

<p>スキーマクラスが Magic::Schema の場合、各テーブルを表すクラスは Magic::Schema::*の名前空間になります。なので spell テーブルは Magic::Schema::Spell として、class_map テーブル はMagic::Schema::ClassMap として、DB から取得できる内容を元に PK やフィールド名、型などが DBIC語で表現されています。</p>

<p>作るといってもメモリ上に作るだけで、lib/Magic/Schema/Spell.pm などのファイルが作られるわけではありませんが、Loader を使わない場合はこれを手動で書く必要があります。フィールドが多いとだるいので、自動でやってくれるのがだいぶ楽です。</p>

<p>使い方の流れが見えたところで、以下の順序で例をもう少し詳しく説明していきます。</p>

<ol>
<li>スキーマクラスの設定</li>
<li>設定の微調整（リレーションの設定）</li>
<li>いろいろな select, update, insert, delete</li>
</ol>

<h3>スキーマクラスの設定</h3>

<p>スキーマクラスに書くコードは <code>loader_options</code> くらいです（<a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader">その他の内容</a>）。その <a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader::Base"><code>loader_options</code> に指定できる内容はここ</a>に列挙されていますが、よく使うのを説明します。</p>

<ul>
<li><em><code>debug =&gt; 1</code></em> ... ON にすると Loader の自動作業内容を出力します。デフォルトはオフです。</li>
<li><em><code>exclude =&gt; qr//</code></em> ... デフォルトでは全テーブルを自動設定しようとしますが、スキップしてほしいテーブル名を正規表現で指定できます。例では、sqlite_ で始まるテーブル（AUTOINCREMENT 使ったので作られた SQLite の内部テーブル）を飛ばしています。</li>
<li><p><em><code>constraint =&gt; qr//</code></em> ... exclude の反対です。例ではテーブル2個だけなので、exclude を使う代わりに以下のように指定することもできます。</p>

<pre><code>constraint =&gt; qr/^( class_map | spell )$/x,
</code></pre></li>
<li><p><em><code>components =&gt; [ ]</code></em> ... ロードするコンポーネントのリストを指定します。</p></li>
</ul>

<h4>DBIC コンポーネント</h4>

<p>DBIC を拡張する方法の基本はこのコンポーネントを追加する方法です。毎回追加してもいいくらい便利なコンポーネントを紹介してみると</p>

<ul>
<li><a href="http://search.cpan.org/perldoc?DBIx::Class::InflateColumn::DateTime">DBIx::Class::InflateColumn::DateTime</a> ... 日付型のフィールドを自動で <a href="http://search.cpan.org/perldoc?DateTime">DateTime</a> オブジェクトに昇華</li>
<li><a href="http://search.cpan.org/perldoc?DBIx::Class::AsFdat">DBIx::Class::AsFdat</a> ... ハッシュでレコードを取りたい時や TT と組み合わせる時に便利</li>
<li><a href="http://search.cpan.org/perldoc?DBIx::Class::UTF8Columns">DBIx::Class::UTF8Columns</a> ... 必ず UTF8 フラグを付けて返すよう指定できる</li>
</ul>

<p>と、コンポーネントは <a href="http://search.cpan.org/search?query=DBIx%3A%3AClass%3A%3A&amp;mode=module">DBIx::Class::なんちゃら</a> という形で CPAN に上げられています。例の3つをロードさせるには、以下のように components に「なんちゃら」部分を並べます。</p>

<pre><code>__PACKAGE__-&gt;loader_options(
    debug =&gt; 1,
    exclude =&gt; qr/^sqlite_/,
    components =&gt; [qw(
        InflateColumn::DateTime
        AsFdat
        UTF8Columns
    )],
);
</code></pre>

<h3>設定の微調整（リレーションの設定）</h3>

<p>自動だけで足りないのは、主にリレーションの設定です。（自動でさせる機能もありますが DB のタイプで対応してなかったり、思ったようにいかない場合もあるので手動で設定する方がいい）</p>

<p>例えば呪文マスタと分類マスタは N:1 の関係で、具体的には spell テーブルの class フィールドが class_map テーブルの id の値なのですが、このリレーションを設定してみます。</p>

<p>lib/Magic/Schema/Spell.pm として以下の内容を保存します。</p>

<pre><code>package Magic::Schema::Spell;
use strict;

__PACKAGE__-&gt;belongs_to(
    class =&gt; 'Magic::Schema::ClassMap'
);

1;
</code></pre>

<p>belong to（属する）という関係で classフィールドを分類マスタ（Magic::Schema::ClassMap）に結びつけています。ここで Magic::Schema::Spellとして手動で書きましたが、この内容が Loader がメモリ上で作成した同名のクラスにうまいことマージされます。</p>

<p>先ほどの test.pl の while 部分を以下のようにしてみてください。</p>

<pre><code>while (my $row = $rs-&gt;next) {
    warn sprintf "* %s: [%s] %s
</code></pre>

<p>", $row->word, $row->class->name, $row->desc;
    }</p>

<pre><code># 結果 ---

* ギラ: [攻撃] 炎
* イオナズン: [攻撃] 爆発で敵全体を攻撃
</code></pre>

<p><a href="http://search.cpan.org/perldoc?DBIx::Class::Relationship">リレーションの設定の書き方はこの POD</a> に書いてあります。設定できる関係は <code>belongs_to</code> 以外に、逆から見た <code>has_many</code> などが用意されています。また、オプションでもっと複雑なリレーションの書き方ができたりもしますが、説明はこのくらいにしておきます。</p>

<h4>どんな SQL が作成されてるか</h4>

<p><a href="http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Manual/Troubleshooting.pod">デバッグの仕方はこの POD</a> に書いてありますが、簡単なのは</p>

<pre><code>export DBIC_TRACE=1
</code></pre>

<p>と DBIC_TRACE 環境変数に1を入れてから perl test.pl することです。SQL 文と、バインドされる値が出力されながら進みます。</p>

<pre><code>SELECT COUNT( * ) FROM spell me: 
13 rows ---
SELECT me.id, me.word, me.class, me.desc, me.ctime FROM spell me: 
SELECT me.id, me.name FROM class_map me WHERE ( ( ( me.id = ? ) ) ): '1'
* メラ: [攻撃] 火の玉
</code></pre>

<p>・・・きっと想像したのとは違う SQL になってると思います。DBIC では SQLの発行を本当に必要なぎりぎりまで伸ばし、またその時々で必要最低限のレコードだけを取得するよう工夫されてたります。もちろんオプションで指示することで SQL を調整可能です。</p>

<h3>いろいろな select, update, insert, delete</h3>

<p>サンプルのように、データにアクセスするには、</p>

<pre><code># スキーマクラスを use し、
use Magic::Schema;

# スキーマクラスのインスタンスを作成
my $schema = Magic::Schema-&gt;connect('dbi:SQLite:dbname=db/spell.db');

# ResultSet を作成し...
my $rs = $schema-&gt;resultset('Spell')-&gt;search;
</code></pre>

<p>と進め、スキーマクラスのインスタンスを作成するには <em>connect()</em> を使うのが普通です。引数は DBI の connect() と一緒です。（さらに<a href="http://search.cpan.org/perldoc?DBIx::Class::Storage::DBI#connect_info">便利に拡張されてます</a>）</p>

<p>DBIC では ResultSet というオブジェクトでデータにアクセスします。ResultSet を取得するには、スキーマの <em>resultset()</em> メソッドなどを使います。resultset() は、spell テーブル（Magic::Schema::Spell）なら Magic::Schema:: 部分を省略した部分（Spell とか ClassMap とか）を指定します。</p>

<p>上の例では取得した ResultSet に search() メソッドで全レコードを取得していますが、他のメソッドは <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSet">DBIC::ResultSet</a> に列挙されています。</p>

<p>この ResultSet がポイントで、DBIC が CDBI とはまったく違うところであり、工夫されてます。ほとんどのメソッドが ResultSet を返すのが特徴で、メソッドを単独で使うこともできればつなげて使うこともできます。この ResultSet が、データが必要になるぎりぎりまで問い合わせを解釈する役割を果たしています。</p>

<p>全部は説明できませんが感じがつかめる程度に例をあげてみます。</p>

<pre><code># 一つのレコードを特定
my $id3 = $schema-&gt;resultset('Spell')-&gt;find(3);
warn "ID 3:" . $id3-&gt;word if $id3;


# 分類が4,5,6のものを作成日の降順で、3行のみ
my $class4 = $schema-&gt;resultset('Spell')-&gt;search({
    class =&gt; [4, 5, 6],
}, {
    order_by =&gt; ['ctime desc'],
    rows     =&gt; 3,
});


# パルプンテの説明を変える
$schema-&gt;resultset('Spell')
        -&gt;search({ word =&gt; "パルプンテ" })
        -&gt;update({ desc =&gt; "何が起きるかわからない。"
                         . "携帯版ドラクエ2だといいことしか起きなかった" });


# ルカニ系削除
$schema-&gt;resultset('Spell')-&gt;search({
    word =&gt; { like =&gt; "ルカ%" },
})-&gt;delete;


# 項目追加
$schema-&gt;resultset('Spell')-&gt;create({
    word  =&gt; "ルカナン",
    class =&gt; 3,
    desc  =&gt; "敵一グループの防御力を下げる",
});


# 名前に「ラ」説明に「い」を含む呪文の最初の一つのみ取得
my $class3 = $schema-&gt;resultset('Spell')-&gt;search_like({
    word  =&gt; "%ラ%",
    desc  =&gt; "%い%",
})-&gt;first;
</code></pre>

<p>どうでしょう。ResultSet のメソッドやオプション、メソッドチェーンや値の取得あたりの使い方のイメージが伝わったでしょうか。</p>

<h3>More</h3>

<p>何でもできそうですが、現実の案件ではだいたい基本機能じゃ足りなくなったりします。しかし、カスタマイズが容易でいろいろな方法が用意されているのも DBIC の特徴で、具体的には以下のような点に手を入れます。</p>

<ul>
<li>コンポーネントを入れる</li>
<li>ResultSource （テーブルを表現したクラス）に好きなメソッドを追加する</li>
<li>ResultSet に好きなメソッドを生やす</li>
</ul>

<p>さて、DBIC は実際はウェブアプリで使うことがほとんどです。View、Model  に続き、次回は MVC で言う Controller を柔軟にこなしてくれるモジュール <a href="http://search.cpan.org/perldoc?Catalyst">Catalyst</a> をとりあげようと思います。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a>, <a href="http://search.cpan.org/perldoc?DBIx::Class::Schema::Loader">DBIx::Class::Schema::Loader</a></p>

<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/B000051TBQ/ele-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/316jImIbnyL.jpg" alt="交響組曲「ドラゴンクエストIII」そして伝説へ…" style="border: none;" /></a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-04-18T01:25:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/010-acme-bleach/">
    <title>use Acme::Bleach;</title>
    <link>http://e8y.net/mag/010-acme-bleach/</link>
    <description>エイプリルフールということで、CPAN のジョークモジュールをいくつか紹介。 CPAN には Acme:: というジョーク専用の名前空間があります。この名前空間が生まれたのは 2001 年。提唱したのは Perl 界の重鎮 Damian で、彼が Bleach というジョークモジュールを作ったときの話らしいです。 最初は Bleach という名前でアップしたのですが、「ジョークモジュールがいろいろ混ざっていくのはいかがなもんかね。ジョーク系は Acme:: という名前空間に入れるようにしませんか」というような感じで提唱。Bleach も Acme::Bleach として再 UP されました。 ...</description>
    <content:encoded><![CDATA[<p>エイプリルフールということで、CPAN のジョークモジュールをいくつか紹介。</p>

<p>CPAN には <em>Acme::</em> というジョーク専用の名前空間があります。この名前空間が生まれたのは 2001 年。提唱したのは Perl 界の重鎮 Damian で、彼が Bleach というジョークモジュールを作ったときの話らしいです。</p>

<p>最初は Bleach という名前でアップしたのですが、「ジョークモジュールがいろいろ混ざっていくのはいかがなもんかね。ジョーク系は Acme:: という名前空間に入れるようにしませんか」というような感じで提唱。Bleach も <a href="http://search.cpan.org/perldoc?Acme::Bleach">Acme::Bleach</a> として再 UP されました。</p>

<p><s>Acme は美味しんぼで言う『究極』とか『至高』とかいうニュアンス</s>と、思ってたのですが、<a href="http://looneytunes.warnerbros.co.jp/stars_of_the_show/wile_roadrunner/wile_story.html">ルーニー・テューンズのロードランナー</a>の中に出てくる、コヨーテに怪しい商品を売る Acme 社 から来てるそうです（<a href="http://use.perl.org/%7Eacme/journal/200">このへん参照</a>）。 メールで教えてもらいました。すみません。</p>

<p>単純に Joke:: とかじゃないのがセンスあるなあと思います。</p>

<p>Acme::Bleach は、</p>

<pre><code>use Acme::Bleach;

print "Hello.";
</code></pre>

<p>みたいに普通に <code>use Acme::Bleach;</code> した後続けて 好きなコードを書いた bleach.pl を作り、実行すると、bleach.pl ファイルそのものが“漂白”され（書き換えられる）、以下のようになります。</p>

<pre>use Acme::Bleach;<br>                                           <br>           
選択してみるとわかりますが、コードがすべて（バイトにされたのち）タブとスペースと改行で表現されてます。use Acme::Bleach; はデコードとエンコード両方の役割を持っており、このまま perl bleach.pl を実行するとちゃんと Hello. を表示します。

とまあ、こうして Acme:: 名前空間ができたおかげで、世界の Perl ハッカーは心置きなく思いついたジョークモジュールを次々 CPAN に投入できるようになったのでした。めでたしめでたし♪

日本人にもわかりやすい Acme:: 系をいくつか紹介してみます。

<h4><a href="http://search.cpan.org/perldoc?Acme::DoubleHelix">Acme::DoubleHelix</a></h4>

Double helix = DNA の 二重らせんです。Acme::Bleach と同じようなモジュールですが、先ほどの Hello. を出力するやつがこうなります。

<pre><code>use Acme::DoubleHelix;

 CG
T--A
A---T
A----T
 C----G
  T----A
   A---T
    G--C
     AT
     CG
    C--G
   G---C
  G----C
 C----G
A----T
C---G
G--C
 TA
 CG
C--G
A---T
A----T

# 以下続く
</code></pre>

<p>こういうのがお好きなら <a href="http://search.cpan.org/perldoc?Acme::EyeDrops">Acme::EyeDrops</a> が気に入ると思います。</p>

<h4><a href="http://search.cpan.org/perldoc?Acme::MorningMusume">Acme::MorningMusume</a></h4>

<p>モーニング娘モジュール。<a href="http://search.cpan.org/%7Ekentaro/Acme-MorningMusume/">1メンバー1モジュール</a>になってて、年齢とかがわかる便利？モジュール。</p>

<h4><a href="http://search.cpan.org/perldoc?Sex">Sex</a></h4>

<p>こいつは、Acme:: ができる前に投入されたジョークモジュール（2000年）で、まだその名前空間のまま生き残ってるやつですね。2つのモジュールを Sex させます。実行時にあえぎます（笑）</p>

<h4><a href="http://search.cpan.org/perldoc?Acme::Hoge">Acme::Hoge</a></h4>

<p>foo や bar を print しようとしても日本風の hoge とか fuga になってしまう、俺は日本男児だー向け？モジュール。</p>

<h4><a href="http://search.cpan.org/perldoc?Acme::Kensiro">Acme::Kensiro</a></h4>

<p><a href="http://www.asahi-net.or.jp/%7Erc4t-ishr/kensiro.html">ケンシロウ進数</a> に基づき「あたたたたた」を出力。くだらない・・・（← Acme:: 系への<em>最高のほめことば</em>です）</p>

<h4><a href="http://search.cpan.org/perldoc?Acme::Hyde">Acme::Hyde</a></h4>

<p>こちらは、ラルクアンシエルの Hyde の身長を 1 とする<a href="http://ja.monapedia.org/wiki/hyde">新たな単位 hyde</a> の計算用モジュール。。</p>

<h4><a href="http://search.cpan.org/perldoc?Acme::Lou">Acme::Lou</a></h4>

<p>これはぼくの作品です。テキストをルー大柴風に変換します。<a href="http://lou5.jp/">ルー語変換</a> で作ったものをモジュール化したものです。結構まじめに組んだ苦心作で、思い出深いモジュールです。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/search?query=Acme%3A%3A&amp;mode=module">その他の Acme:: モジュール</a>, <a href="http://www.perlmonks.org/?node_id=410774">Acme:: 名前空間誕生秘話</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-04-01T20:53:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/009-dbix-simple/">
    <title>use DBIx::Simple;</title>
    <link>http://e8y.net/mag/009-dbix-simple/</link>
    <description>今みたら、読者数60人を超えてました。このメルマガは会社にしか告知していなくて、会社で登録してるのはとりあえず3,4人です。せっかく書くならまぐまぐにしておけば、誰かが見つけて登録してくれるかも、とか思っていたのですが、意外とたくさん登録してくれていてうれしいです。 今回はデータベースまわりのモジュールを取り上げます。 Perl から DB 接続するときは DBI.pm を使うというのは定番で、これはすばらしいモジュールなのですが、ステートメントハンドラが出てきたりレイヤーとしては低い層の API です。そこで普通なにがしかのラッパーモジュール経由で DBI を使います。  軽量・シンプルで小...</description>
    <content:encoded><![CDATA[<p>今みたら、読者数60人を超えてました。このメルマガは会社にしか告知していなくて、会社で登録してるのはとりあえず3,4人です。せっかく書くならまぐまぐにしておけば、誰かが見つけて登録してくれるかも、とか思っていたのですが、意外とたくさん登録してくれていてうれしいです。</p>

<p>今回はデータベースまわりのモジュールを取り上げます。</p>

<p>Perl から DB 接続するときは <a href="http://search.cpan.org/perldoc?DBI">DBI.pm</a> を使うというのは定番で、これはすばらしいモジュールなのですが、ステートメントハンドラが出てきたりレイヤーとしては低い層の API です。そこで普通なにがしかのラッパーモジュール経由で DBI を使います。 </p>

<p>軽量・シンプルで小粋なラッパーをご所望であれば、<a href="http://search.cpan.org/perldoc?DBIx::Simple">DBIx::Simple</a> がおすすめです。もっといろんなことを期待するのであれば、本格 ORマッパー <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a> がいちおしです。 </p>

<p>今回は <em>DBIx::Simple</em> を解説します。Web 系アプリでは DBIx::Class を使うことのほうが多いですが、簡単な処理系バッチを書くときなどは DBIx::Simple の方を使うこともあります。 </p>

<p>使い方は簡単です。素の DBI.pm での操作と比較しながら見てみてください。 </p>

<h3>接続</h3>

<p>接続まわりは DBI と同じです。 </p>

<pre><code># MySQLの例
my @dsn = (
    'dbi:mysql:host=localhost;database=test;',
    'test',
    'test',
    { RaiseError =&gt; 1 },
);

my $db = DBIx::Simple-&gt;connect(@dsn)
  or die DBIx::Simple-&gt;error;

# SQLiteの例
my $db = DBIx::Simple-&gt;connect('dbi:SQLite:dbname=../db/hoge.db')
  or die DBIx::Simple-&gt;error;
</code></pre>

<p>テスト用テーブルを作っておくといろいろ試せてよいです。今回以下のようなスキーマを前提に話を進めます。</p>

<p><a href="http://e8y.net/mag/009-dbix-simple/sample.sql">http://e8y.net/mag/009-dbix-simple/sample.sql</a>（文字コードUTF-8、SQLite 用 create 文です）</p>

<h3>SQL文の実行</h3>

<p>一番基本的なクエリ発行は <em><code>query()</code></em> です。以下のように使います。</p>

<pre><code>my $rs = $db-&gt;query('select * from spell where class = ?', 1) 
  or die $db-&gt;error;
</code></pre>

<p>query() の第一引数に SQL文、2個目以降に <em>?</em> にバインドする値を渡します。そして結果のオブジェクトが返ります。（失敗した場合は 偽 が返り、上記のように <em>$db->error</em> でエラー内容を取り出せます）</p>

<p>この結果オブジェクト（DBIx::Simple::Result）がいい感じです。</p>

<h3>DBIx::Simple::Result</h3>

<h4>件数</h4>

<p>件数を引くには <em><code>$rs-&gt;rows()</code></em> を使います。 </p>

<pre><code>print "Results:". $rs-&gt;rows;
</code></pre>

<p><code>query()</code> に渡した SQL が更新系（insert, update, delete）だった場合は、影響を受けた件数が取れます。</p>

<p><em>データのイテレート</em> </p>

<p>select系の場合は、結果オブジェクトの <em><code>hash()</code></em> というメソッドを使うと、以下のように結果をハッシュで受け取りながらイテレートできます。 </p>

<pre><code>use Data::Dumper;

while (my $row = $rs-&gt;hash) {
    warn Dumper $row;
}

# 結果 ---

$VAR1 = {
          'word' =&gt; 'メラ',
          'desc' =&gt; '火の玉をぶつける',
          'class' =&gt; '1'
        };
$VAR1 = {
          'word' =&gt; 'ギラ',
          'desc' =&gt; '炎',
          'class' =&gt; '1'
        };
</code></pre>

<p><code>$rs-&gt;hash</code> のところを <em><code>array()</code></em> に変えると、ハッシュじゃなくリストリファレンスで行を取得できます。</p>

<pre><code>my $rs = $db-&gt;query('select desc, word from spell where class = ?', 2);

while (my $row = $rs-&gt;array) {
    warn Dumper $row;
}

# 結果 ---

$VAR1 = [
          'HPを回復する',
          'ホイミ'
        ];
$VAR1 = [
          '毒を治療する',
          'キアリー'
        ];
$VAR1 = [
          '生き返らせる',
          'ザオリク'
        ];
</code></pre>

<p>ほかにも、渡した変数に展開する <em><code>into()</code></em> という小技もあります。</p>

<pre><code>my $rs = $db-&gt;query('select word, classmap.name 
                     from spell left join classmap 
                     on spell.class = classmap.id
                     limit 3');

while ( my $row = $rs-&gt;into( my ($word, $class) ) ) {
    warn "* $word ($class系)
</code></pre>

<p>";
    }</p>

<pre><code># 結果 ---

* メラ (攻撃系)
* ギラ (攻撃系)
* ホイミ (回復系)
</code></pre>

<p><code>count(*)</code> の結果など、値を直接を受け取りたい場合は、<em><code>list()</code></em> という <code>array()</code> のリファレンスにならないバージョンを使います。 </p>

<pre><code>my ($count) = $db-&gt;query('select count(*) from spell')-&gt;list;
</code></pre>

<h4>結果の全取得</h4>

<p><em><code>hashes()</code></em> や <em><code>arrays()</code></em> を使うと、全行が返ります。</p>

<pre><code>my $set = $db-&gt;query('select word, desc from spell class = ?', 3)-&gt;hashes;
warn Dumper $set;

# 結果 ---

$VAR1 = [
          {
            'word' =&gt; 'バルシーラ',
            'desc' =&gt; 'ふっとばす'
          },
          {
            'word' =&gt; 'ギラ',
            'desc' =&gt; '消し去る'
          },
          {
            'word' =&gt; 'モシャス',
            'desc' =&gt; '能力をコピーする'
          }
        ];
</code></pre>

<p>全取得メソッドは、上記のようにスカラで受け取ればリストのリファレンスに、<code>@set =</code> とリストで受け取ればリストで受け取れます。</p>

<p>実際は <code>$rs-&gt;hash()</code> を while で回すことが多いので全取得はあまり使いませんが、<em><code>map_hashes()</code></em> という、あるフィールドをキーにしたハッシュの構造体にして返すというのが便利なのでたまに使います。 </p>

<pre><code>my $rs = $db-&gt;query('select word, classmap.name, desc 
                     from spell left join classmap 
                     on spell.class = classmap.id
                     where class &gt;= 4');

warn Dumper { $rs-&gt;map_hashes('word') };

# 結果 ---

$VAR1 = {
          'ラリホー' =&gt; {
                          'desc' =&gt; '眠らせる',
                          'name' =&gt; '防御'
                        },
          'マホトーン' =&gt; {
                            'desc' =&gt; '相手の呪文を無効にする',
                            'name' =&gt; '防御'
                          },
          'ルーラ' =&gt; {
                        'desc' =&gt; '移動する',
                        'name' =&gt; '移動'
                      }
        };
</code></pre>

<p>色物的ですが、DBIx::XHTML_Table や Text::Table というモジュールとの連携も組み込まれていて、<code>html()</code></p>

<pre><code>print $db-&gt;query('select word as "呪文", desc as "説明" from spell limit 2')-&gt;html;
</code></pre>

<p>で以下みたいな HTML テーブルを書き出せたり（内部で <a href="http://search.cpan.org/perldoc?DBIx::XHTML_Table">DBIx::XHTML_Table</a> を使っています）</p>

<pre><code>&lt;table&gt;
        &lt;thead&gt;
        &lt;tr&gt;
                &lt;th&gt;呪文&lt;/th&gt;
                &lt;th&gt;説明&lt;/th&gt;
        &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
        &lt;tr&gt;
                &lt;td&gt;メラ&lt;/td&gt;
                &lt;td&gt;火の玉をぶつける&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
                &lt;td&gt;ギラ&lt;/td&gt;
                &lt;td&gt;炎&lt;/td&gt;
        &lt;/tr&gt;
        &lt;/tbody&gt;
&lt;/table&gt;
</code></pre>

<p>また、<code>text()</code></p>

<pre><code>print $db-&gt;query('select class, word from spell where class = ?', 4)-&gt;text('table');
</code></pre>

<p>で以下みたいなアスキーテーブルを書き出せたり（内部で <a href="http://search.cpan.org/perldoc?Text::Table">Text::Table</a> を使っています）します。日本語の数え方の問題でアスキーテーブルはちょっと崩れてしまいますが。おまけ機能的な感じですね。</p>

<pre><code>class |      word      
------+----------------
  4   | ラリホー   
  4   | マホトーン
</code></pre>

<p>このように、DBIx::Simple の結果オブジェクトは直感的にデータを引き出せて便利です。しかし、DBIx::Simple がオススメなのはこれだけじゃなくて、<a href="http://search.cpan.org/perldoc?SQL::Abstract">SQL::Abstract</a> という名モジュールが組み込まれていることにあります。</p>

<h3>SQL::Abstract</h3>

<p>結果オブジェクトを取得するのに、上記例では query() を使っていましたが、その代わりに <em><code>select()</code></em>、<em><code>insert()</code></em>、<em><code>update()</code></em>、<em><code>delete()</code></em> というそのまんまなメソッドを使うことができます。SQL 文とプレースホルダ形式よりだいぶわかりやすいです。裏側で、SQL::Abstract が Perl の構造式を SQL 文に変換してくれます。</p>

<p>※ 現在のバージョン（1.27）では、select()、insert()、update()、delete() を使う前に <code>$db-&gt;abstract;</code> が必要です。<a href="http://rt.cpan.org/Public/Bug/Display.html?id=18629">バグレポート出したのですが</a>最近返事があったので近く作者が修復してくれるはずです。（追記：修復済みです）</p>

<p>使い方ですが、例えば </p>

<pre><code>my $rs = $db-&gt;query('select word, desc from spell 
                     where word (class = ? OR class = ?) and 
                     desc like ?', 2, 3, "%回復%");
</code></pre>

<p>の代わりに、以下のようにできます。</p>

<pre><code>my $rs = $db-&gt;select('spell', ['word', 'desc'], {
    class =&gt; [ 2, 3 ],
    desc =&gt; { like =&gt; '%回復%' },
});
</code></pre>

<p>insert などは、abstract メソッドの方がよっぽどわかりやすいです。</p>

<pre><code>my $rs = $db-&gt;query('insert into spell (word, class, desc) values (?, ?, ?)', 
                    "パルプンテ", 6, "何が起こるかわからない");
</code></pre>

<p>は insert() だとこう書けます。</p>

<pre><code>my $rs = $db-&gt;insert('spell', {
    word  =&gt; "パルプンテ",
    class =&gt; 6,
    desc  =&gt; "何が起こるかわからない",
});
</code></pre>

<p>他の例については、<a href="http://search.cpan.org/dist/DBIx-Simple/lib/DBIx/Simple/Examples.pod">Examples</a> をながめるとつかめると思います。</p>

<h3>More</h3>

<p>LEFT JOIN などのリレーションをもっと透過的に操作したいとか、日付型フィールドは日付オブジェクトとして扱いたい、など、もっと高度なモデルが欲しい場合も多いと思います。</p>

<p>そんなときは今なら DBIx::Class という うってつけのものがあります。次回はこれを取り上げる予定です。DBIx::Class も同じ SQL::Abstract を使っており、DBIx::Simple から DBIx::Class への移行は比較的簡単です。 </p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?DBIx::Simple">DBIx::Simple</a>, <a href="http://search.cpan.org/dist/DBIx-Simple/lib/DBIx/Simple/Examples.pod">例いろいろ</a>, <a href="http://search.cpan.org/dist/DBIx-Simple/lib/DBIx/Simple/Comparison.pod">DBI.pm との比較</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-03-20T13:25:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/008-template/">
    <title>use Template;</title>
    <link>http://e8y.net/mag/008-template/</link>
    <description> 2008/1/1 - 内容が薄かったので大幅に書き足しました。 これから数回は、仕事でよく使う大型モジュールを中心に紹介して行こうと思います。まずは、Templateです。ディストリビューション名は Template-Toolkit というので、TT と呼ばれます。  CPAN は、こういったトップレベル（モジュール名に :: がつかない）の名前空間はよほどのものでないと使わないようにということになっています。いちおう。その点、Template は「テンプレート」を名乗るにふさわしい、一級のモジュールです。 要するに Perl 版 JSP と言えば早いでしょうか。非常に強力なのでテンプレート...</description>
    <content:encoded><![CDATA[<ul>
<li>2008/1/1 - 内容が薄かったので大幅に書き足しました。</li>
</ul>

<p>これから数回は、仕事でよく使う大型モジュールを中心に紹介して行こうと思います。まずは、<a href="http://search.cpan.org/dist/Template-Toolkit"><em>Template</em></a>です。ディストリビューション名は <em>T</em>emplate-<em>T</em>oolkit というので、<em>TT</em> と呼ばれます。 </p>

<p>CPAN は、こういったトップレベル（モジュール名に :: がつかない）の名前空間はよほどのものでないと使わないようにということになっています。<em>いちおう</em>。その点、Template は「テンプレート」を名乗るにふさわしい、一級のモジュールです。</p>

<p>要するに Perl 版 JSP と言えば早いでしょうか。非常に強力なのでテンプレート側でいろいろできちゃったりしますので使い方はあなた次第、という感じです。が、いざという時（きれいなロジックを書いてるヒマがなかった時とか...）助かります。</p>

<p>コード側は簡単で、以下のように使います。</p>

<pre><code>use Template;

# インスタンスを作成し、
my $tt = new Template;

my $vars = { 
    name =&gt; "とみた", 
    age =&gt; 28, 
};

# test.tt テンプレートファイルに $vars をバインドして出力
$tt-&gt;process('test.tt', $vars)
    or die $tt-&gt;error;
</code></pre>

<p><em><code>process()</code></em> メソッドだけ覚えておけばよく、<em>1番目がテンプレート</em>、<em>2番目が変数のハッシュ</em>です。test.tt ファイルには、例えば以下のように書いておくと、 </p>

<pre><code>「[% name %]さん、あと[% 30 - age %]才で30ですよ」
</code></pre>

<p>「とみたさん、あと2才で30ですよ」と出力されます。テンプレートファイルの拡張子は何でもいいですが、TT なので .tt とする人が多いです。</p>

<p>1番目の引数にはファイル名以外に、ファイルハンドルやテキストそのものも渡せます。これらを渡すときはリファレンスで渡します。</p>

<pre><code>$tt-&gt;process(*DATA, $vars); # DATAファイルハンドル

my $text = "My name is [% name %].";
$tt-&gt;process($text, $vars); # テキストのリファレンス
</code></pre>

<p>私は<a href="http://e8y.net/labs/tagcloud/">これ</a>のようにコネタ系 CGI を書くときDATA ファイルハンドルを使ったりします。一つのファイルに <code>__DATA__</code> 前後でまとめて入れられるので気に入っています。</p>

<p><code>process()</code> はデフォルトは標準出力に結果を出しますが、結果を変数、例えば <code>$out</code> に入れたい場合は<em>3番目に格納先変数をリファレンスで</em>渡します。</p>

<pre><code>$tt-&gt;process('template-test.tt', $vars, my $out)
    or die $tt-&gt;error;
</code></pre>

<h3>シンタックス 基本編</h3>

<p>では、そんな TT の強力っぷりについてできるだけ説明してみます。それぞれ簡単にしか説明できないので、詳しくはそれぞれの項目に置いた POD のリンクも参照してください。</p>

<ul>
<li><p><em>TT タグ</em>（<a href="http://search.cpan.org/dist/Template-Toolkit/lib/Template/Manual/Config.pod#TAG_STYLE">POD</a>）</p>

<p>基本は <code>[%</code> と <code>%]</code> 内が TT エリアとなりますが、インスタンスを作るときの TAG_STYLE オプションで <code>&lt;? ?&gt;</code> とか <code>&lt;% %&gt;</code> とか <code>&lt;!-- --&gt;</code> とかに好きに設定できます。</p>

<pre><code>my $tt = new Template({ 
    TAG_STYLE =&gt; 'html', # &lt;!-- と --&gt; を使う
});
</code></pre>

<p>他にもテンプレート内で指定しちゃうこともできます。途中から変えるのも有り。</p>

<pre><code>[% foo.bar %]...
[% TAGS html %] ここからは HTML コメントスタイル
&lt;!-- foo.bar --&gt;
&lt;!-- TAGS default --&gt; ここから戻る
[% foo.bar %]...
</code></pre></li>
<li><p><em>TT タグ前後の改行</em>（<a href="http://search.cpan.org/dist/Template-Toolkit/lib/Template/Manual/Config.pod#PRE_CHOMP">POD</a>）</p>

<pre><code>『こんにちは
[% IF name %]
、[% name %]さん
[% END # IF %]
。』
</code></pre>

<p>は</p>

<pre><code>『こんにちは
、とみたさん
。』
</code></pre>

<p>と出力されます。HTML の場合改行は問題なかったりしますが、以下のように TT タグの内側にハイフンをつけるとその方向の空文字が消え、<code>『こんにちは、とみたさん。』</code>とつながって出ます。</p>

<pre><code>『こんにちは
[%- IF name %]
、[% name %]さん
[% END # IF -%]
。』
</code></pre></li>
<li><p><em>変数へのアクセス</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Variables">POD</a>）</p>

<pre><code>$tt-&gt;process('test.tt', {
    name =&gt; 'とみた',
    hatena =&gt; 'tomi-ru',
    skill =&gt; ['迷子', '寝坊'],
    favorite =&gt; {
        game =&gt; 'ドラクエ３',
        movie =&gt; 'インディペンデンスデイ',
    },
    birthday =&gt; DateTime-&gt;new(year=&gt;'1979', month=&gt;'1', day=&gt;'4'),
    hello =&gt; sub {
        my $word = shift;
        return "こんにちは $word。";
    },
});
</code></pre>

<p>というような形で変数があった場合、以下のようにアクセスします。Ruby のように ドットでたどります。TT は HTML で使うことが多いので、<code>-&gt;</code> でなくドットでたどれるのはいい感じです。</p>

<pre><code>&lt;dl&gt;
    &lt;dt&gt;名前:&lt;/dt&gt;
    &lt;dd&gt;[% name %]&lt;/dd&gt;
    &lt;dt&gt;特技:&lt;/dt&gt;
    &lt;dd&gt;[% skill.0 %], [% skill.1 %]&lt;/dd&gt;
    &lt;dt&gt;好きな映画: &lt;/dt&gt;
    &lt;dd&gt;[% favorite.movie %]&lt;/dd&gt;
    &lt;dt&gt;誕生日:&lt;/dt&gt;
    &lt;dd&gt;[% birthday.strftime('%Y年%m月%d日') %]&lt;/dd&gt;
    &lt;dt&gt;ひとこと:&lt;/dt&gt;
    &lt;dd&gt;[% hello("みなさん") %]&lt;/dd&gt;
    &lt;dt&gt;はてな:&lt;/dt&gt;
    &lt;dd&gt;[% "http://d.hatena.ne.jp/" _ hatena _ "/about" %]&lt;/dd&gt;
&lt;/dl&gt;
</code></pre>

<p>なお、_で始まる変数は変数側では参照できません。</p></li>
<li><p><em>四則演算</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Directives#GET">POD</a>）・ <em>比較</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Directives#IF_/_UNLESS_/_ELSIF_/_ELSE">POD</a>）</p>

<p><code>+ - * / % and or not ?:</code> は Perl と同じに使えます。文字列の連結だけ <code>.</code> じゃなくて <code>_</code> になります。比較演算子も <code>== != &lt; &lt;= &gt; &gt;= &amp;&amp; || ! and or not</code> が Perl と同じに使えます。</p>

<pre><code>[% 30 - age &lt;= 0 ? "もう" _ age : "まだ" _ age %]
</code></pre></li>
<li><p><em>仮想メソッド</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::VMethods">POD</a>）</p>

<p>どんな変数にもくっつけることができるスーパーオブジェクト関数のようなものがたくさん用意されていて、文字列操作が多いテンプレートまわりで役立ちます。よくできた言語になっています。以下は一例です。</p>

<pre><code>[% date = "2008-01-01";
   date.remove('^200[0-9]-');  # 01-01
   date.replace('-0?', '/');  # 2008/1/1
   date.split('-').join('/');  # 2008/01/01
   date.search('^2008');  # true(1)


   m = date.match('(d+)-(d+)-(d+)');
   m.0;  # 2008


   abc = ["z", "a", "a", "b", "c"];
   abc.size;  # 5
   abc.unique.sort.join('/');  # a/b/c/z


   map = {
      one =&gt; 1,
      two =&gt; 2,
      three =&gt; 3,
   };
   map.keys;  # ["one", "two", "three"] ※順不同
   map.values.sort.join('-');  # 1-2-3
%]
</code></pre>

<p>例のように、<code>[% %]</code> 内に複数の文を入れるときは、セミコロンで区切ります。また、# 以降はコメントとなります。</p></li>
<li><p><em>フィルタ</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Filters">POD</a>）</p>

<p>HTMLエスケープなどの最終処理用に、<code>|</code> を使ったフィルタというシンタックスがあり、デフォルトでよく使うものが複数用意されています。</p>

<pre><code>[% title | html %]
</code></pre>

<p><a href="http://search.cpan.org/perldoc?Template::Manual::Filters#html"><code>html</code></a> や <a href="http://search.cpan.org/perldoc?Template::Manual::Filters#uri"><code>uri</code></a>、改行を <code>&lt;br /&gt;</code> に変える <a href="http://search.cpan.org/perldoc?Template::Manual::Filters#html_line_break"><code>html_line_break</code></a> なんかを良く使います。HTML エスケープして改行を <code>&lt;br /&gt;</code> にする場合は以下のようにつなげます。</p>

<pre><code>&lt;p&gt;[% daily.body | html | html_line_break %]&lt;/p&gt;
</code></pre></li>
<li><p><em>IF文など制御構文</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Directives#IF">POD</a>）</p>

<p>TT の制御構文キーワードは大文字で、Perl とは少し違います。どれも <code>END</code> で終われるので、ネストした時にわかるよう、<code>END # IF</code> とかするとわかりやすいです。</p>

<ul>
<li><p><a href="http://search.cpan.org/perldoc?Template::Manual::Directives#IF">IF</a></p>

<pre><code>[% IF a == "A" and (b &lt;= 3 and c &gt; 4) %]
foo
[% ELSIF not d %]
bar
[% ELSE %]
gee
[% END # IF %]
</code></pre></li>
<li><p><a href="http://search.cpan.org/perldoc?Template::Manual::Directives#SWITCH">SWITCH</a></p>

<pre><code>[% SWITCH x %]
[% CASE "A" %] Aの時（breakはいらないです）
[% CASE ["B", "C"] %] BかCの時
[% CASE %] 指定しないと、それ以外
[% END # SWITCH %]
</code></pre></li>
<li><p>リストと <a href="http://search.cpan.org/perldoc?Template::Manual::Directives#FOREACH">FOREACH</a></p>

<pre><code>[% var = ["a", "b", "c", "d", "e"] %]
&lt;ul&gt;
[% FOREACH v = var;
      NEXT IF v == "b";
      LAST IF v == "e";
%]
&lt;li&gt;[% v %]&lt;/li&gt;
[% END # FOREACH %]
&lt;/ul&gt;
</code></pre></li>
<li><p>ハッシュと FOREACH</p>

<pre><code>[% unit = {
      ja =&gt; 'yen',
      us =&gt; 'dollar',
      eu =&gt; 'euro',
   }
%]


[% FOREACH u IN unit %]
* [% u.key %]: [% u.value %]
[% END # FOREACH %]
</code></pre></li>
<li><p>ハッシュのリストと FOREACH</p>

<pre><code>[% rank = [
      { name =&gt; 'usagi', color =&gt; 'white' },
      { name =&gt; 'kame',  color =&gt; 'green' },
   ];
%]


[% FOREACH r IN rank %]
No.[% loop.count %]
   [% r.name %] ([% r.color %])
[% END # FOREACH %]
</code></pre>

<p>※ loop というのは FOREACH 内部で利用できる特別な変数で、count 以外に index などがあります。どの FOREACH 内でも利用できます。</p></li>
<li><p><a href="http://search.cpan.org/perldoc?Template::Manual::Directives#WHILE">WHILE</a></p>

<pre><code>[% WHILE (row = rs.next) %]
[% row.id %] - [% row.name %]
[% END # WHILE %]
</code></pre></li>
</ul></li>
</ul>

<h3>シンタックス 発展編</h3>

<ul>
<li><p><em>WRAPPER</em>（<a href="http://search.cpan.org/perldoc?Template::Manual::Directives#WRAPPER">POD</a>）</p>

<p>HTML出力に TT を使う場合、共通ヘッダやフッタ部分などをまとめたいという話が出てくると思います。もちろん普通の <a href="http://search.cpan.org/perldoc?Template::Manual::Directives#INCLUDE">INCLUDE のしくみ</a>もありますが、<a href="http://search.cpan.org/perldoc?Template::Manual::Directives#WRAPPER">WRAPPER</a> という仕組みが便利です。まず、</p>

<pre><code>&lt;html&gt;
&lt;head&gt;
&lt;title&gt;[% title _ " - " | html IF title %]&lt;title&gt;
[% IF jquery %]
&lt;script type="text/javascript" src="jquery.js"&gt;&lt;/script&gt;
[% END %]
&lt;/head&gt;
&lt;body&gt;
[% content %]
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>という <code>[% content %]</code> を含むテンプレートを、例えば wrapper.tt という名前で用意しておきます。そして、test.tt を WRAPPER ディレクティブで囲みます。</p>

<pre><code>[% WRAPPER wrapper.tt;
   title = "目次"
   jquery = 1
%]


コンテンツ


[% END # WRAPPER %]
</code></pre>

<p>これで、<code>$tt-&gt;process('test.tt')</code> すると、WRAPPER ディレクティブ内が wrapper.tt の [% contents %] のところに埋め込まれます。コンテンツの上下にヘッダとフッタを2回 INCLUDE するよりわかりやすいです。ラッパーの方でも呼び出し元テンプレートの変数を参照できますので、例のようにタイトルとかを渡すと良いです。</p>

<p>ちなみに、FOREACH の中の loop のように、TT が用意する特別な変数があって、template と component というのがあります。</p>

<ul>
<li><code>[% template.name %]</code> にはラッパーした側 された側 関係なく <code>$tt-&gt;process</code> された大元のファイル名が入っています。</li>
<li><code>[% component.name %]</code> にはラッパーした側 された側 関係なく、自分のファイル名が入っています。</li>
</ul>

<p><a href="http://search.cpan.org/perldoc?Template::Manual::Directives#META">META</a> で template に簡単な変数を入れることもでき、タイトル名などはここに入れて渡すのを好む人もいるようです。</p></li>
<li><p><em>USE</em> プラグイン（<a href="http://search.cpan.org/perldoc?Template::Manual::Plugins">POD</a>）</p>

<p>それでも不足がある場合は、プラグインで強化することができます。たとえば</p>

<ul>
<li><p><a href="http://search.cpan.org/perldoc?Template::Plugin::Dumper">Template::Plugin::Dumper</a> を使うと TT 内で Dumper できます。プラグインは以下のように USE 構文を使い Template::Plugin:: 以降を指定します。 </p>

<pre><code>[% USE Dumper %]
[% Dumper.dump(template) %]
</code></pre></li>
</ul>

<p>Dumper など <a href="http://search.cpan.org/perldoc?Template::Manual::Plugins">TT に同梱のプラグイン</a>もけっこうありますが、 ほかにもたくさんのプラグインが <a href="http://search.cpan.org/search?query=Template%3A%3APlugin%3A%3A&amp;mode=module">Template::Plugin:: 名前空間</a>にあります。TT は人気があるので、かゆいところに手がとどくのが揃っているわけです。たとえば、</p>

<ul>
<li><p><a href="http://search.cpan.org/perldoc?Template::Plugin::Comma">T::P::Comma</a> は、数値をカンマ区切りするフィルタを追加してくれます。10,000 とかになります。</p>

<pre><code>[% USE Comma %]
&amp;yen; [% yen | comma %]
</code></pre></li>
<li><p><a href="http://search.cpan.org/perldoc?Template::Plugin::Clickable">T::P::Clickable</a> という、URL ぽいものを <code>&lt;a&gt;</code> タグでリンクにしてくれるフィルタもあります。 </p>

<pre><code>[% USE Clickable %]
[% entry | html | clickable %]
</code></pre></li>
<li><p><a href="http://search.cpan.org/perldoc?Template::Plugin::JapanesePrefectures">T::P::JapanesePrefectures</a> は、よくある都道府県 <code>&lt;select&gt;</code> を作るのを楽できます。 </p>

<pre><code>[% USE prefs = JapanesePrefectures('utf-8') %]
&lt;select name="pref"&gt;
    &lt;option value=""&gt;選択してください&lt;/option&gt;
    [% FOR p IN prefs.prefectures %]
    &lt;option value="[% p.name | id %]"&gt;[% p.name %]&lt;/option&gt;
    [% END %]
&lt;/select&gt;
</code></pre></li>
</ul></li>
</ul>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/dist/Template-Toolkit/">Template</a>, <a href="http://www.hakoniwa.net/tt/">良く使う部分の和訳</a></p>

<p>和訳されていませんが、専門に扱った書籍が出ています。 <br />
<a href="http://www.amazon.co.jp/dp/0596004761?tag=ele-22&amp;camp=243&amp;creative=1615&amp;linkCode=as1&amp;creativeASIN=0596004761&amp;adid=03NY2KDS9X80HKZ7MPXP&amp;"><img src="http://rcm-images.amazon.com/images/P/0596004761.01._SL100_SCTZZZZZZZ_.jpg" alt=""></a></p>

<p>その他プロダクションでも使われる View モジュールには、<a href="http://search.cpan.org/perldoc?HTML::Mason">Mason</a> や <a href="http://search.cpan.org/perldoc?HTML::Template">HTML::Template</a> などがあります。 </p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-25T03:01:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/007-www-mechanize/">
    <title>use WWW::Mechanize;</title>
    <link>http://e8y.net/mag/007-www-mechanize/</link>
    <description>WWW::Mechanize を使うと、人間がブラウザですること （URL を開き、リンクをたどり、ID・Pass を入力、ログインボタンを押す…） を Perl にエミュレートさせることができます。略称 Mech（メック）。あまりに簡単・便利なのでなにかと悪用されることも多いモジュールです（うそです）。 Perl での HTTP 通信まわりは、LWP (libwww-perl) ファミリーが担当しており、ウェブの HTTP リクエストは LWP::UserAgent モジュールを使って操作します。 Mech はその LWP::UserAgent の高度なラッパーモジュールです。LWP::Us...</description>
    <content:encoded><![CDATA[<p><a href="http://search.cpan.org/perldoc?WWW::Mechanize"><em>WWW::Mechanize</em></a> を使うと、人間がブラウザですること （URL を開き、リンクをたどり、ID・Pass を入力、ログインボタンを押す…） を Perl にエミュレートさせることができます。略称 Mech（メック）。あまりに簡単・便利なのでなにかと悪用されることも多いモジュールです（うそです）。</p>

<p>Perl での HTTP 通信まわりは、<a href="http://search.cpan.org/dist/libwww-perl/">LWP</a> (libwww-perl) ファミリーが担当しており、ウェブの HTTP リクエストは <a href="http://search.cpan.org/perldoc?LWP::UserAgent">LWP::UserAgent</a> モジュールを使って操作します。</p>

<p>Mech はその LWP::UserAgent の高度なラッパーモジュールです。LWP::UserAgent の 全機能に加え、cookie の処理やヒストリ（戻るボタンに相当）、HTMLを人が見るように扱えるよう解析、といった処理を自動で行なってくれる<em>賢い</em>モジュールです。素で LWP::UserAgent を使ってやることもできますがかなりめんどうです。</p>

<p>しかも使い方は簡単で、 </p>

<pre><code>use WWW::Mechanize;
my $mech = new WWW::Mechanize( autocheck =&gt; 1 );
</code></pre>

<p>と、インスタンスを作成した後、</p>

<pre><code>$mech-&gt;get("http://www.google.co.jp/");
$mech-&gt;submit_form(...
$mech-&gt;get(...
</code></pre>

<p>というように、Mech のメソッドを並べブラウジングをエミュレートしていきます。</p>

<p>（なお、new に渡した <code>autocheck =&gt; 1</code> は、リクエストに失敗した時そこで die するという意味です。autocheck しない場合は <code>$mech-&gt;success</code> などで手動でチェックする必要があります）</p>

<p>Mech のメソッドはいろいろありますが、基本的に以下の3つのメソッドだけで、行きたいページまでたどれるはずです。 </p>

<ul>
<li><p><em><code>get()</code></em> <br />
引数で指定したURLを開きます。</p>

<pre><code>$mech-&gt;get('http://www.google.co.jp/blogsearch?hl=ja&amp;amp;q=link:e8y.net&amp;amp;scoring=d');
</code></pre></li>
<li><p><em><code>follow_link()</code></em> <br />
今いるページ内で、引数で指定した条件のリンクを探し、クリック（移動）します。指定できる条件には</p>

<pre><code>url     - そのリンクのURL。a タグなら href の値
url_abs - 絶対パスにしたもの。http://e8y.net/index.html にある 
           &lt;a href="/blog/" は http://e8y.net/blog/ となる。
text    - そのリンクのタグの innerHTML
name    - name 属性の値
tag     - タグ名。a や frame、iframe のように小文字で来ます
</code></pre>

<p>例えば、</p>

<pre><code>$mech-&gt;follow_link(text =&gt; "もっと読む");
</code></pre>

<p>で、「もっと読む」というリンクを探しクリックしたように遷移します。</p>

<p>それぞれの条件名の後に <em><code>_regex</code></em> をつけると、正規表現で指定できます。あと、 <em><code>n =&gt;</code></em> でその何番目、というのを指定できます（指定しない場合は、最初に見つかったリンクに飛びます）。これらは、好きに組み合わせることができます。</p>

<pre><code>$mech-&gt;follow_link( 
    text_regex =&gt; qr/^全てを見る/,
    url_abs_regex =&gt; qr{^http://mixi.jp/},
    n =&gt; 2,
);
</code></pre>

<p>これで、『テキストが「全てを見る」で始まり、mixi.jp のドメイン内のリンクで、2番目にあるもの』をクリック となります。  </p></li>
<li><p><em><code>submit_form()</code></em> <br />
引数で指定した要領でフォームをクリックし次へ進みます。以下のように、<em><code>fields =&gt;</code></em> にハッシュリファレンスの形でフォームの値を指定します。</p>

<pre><code>$mech-&gt;submit_form(
    fields =&gt; {
        email =&gt; 'test@example.com',
        password =&gt; 'p4ssw0rd',
    },
);
</code></pre>

<p>follow_link と同じように、何も指定しない場合は一番最初に出てきたフォームに対して処理が行なわれます。なので、引数なしでただ <code>$mech-&gt;submit_form()</code> を実行すると、ページの最初のフォームのデフォルト値そのまま送信されます。</p>

<p>フォームが複数ある場合は <em><code>form_number =&gt;（何番目）</code></em>や <em><code>form_name =&gt;（nameの値）</code></em>で明示的に指定することもできます。また、フォームの中に Submit ボタンがたくさんある場合には <em><code>button =&gt;（nameの値）</code></em> で指定できます。たいていは <code>fields =&gt;</code> だけでよいと思います。  </p></li>
</ul>

<p>そして、現在の HTML の内容そのものは <em><code>$mech-&gt;content</code></em> で取得できます。</p>

<h3>EXAMPLES</h3>

<h4>Mixiにログインし、足あとページを取得</h4>

<pre><code>my $mech = new WWW::Mechanize( autocheck =&gt; 1 );

# トップにアクセスし、
$mech-&gt;get('http://mixi.jp/');

# ログイン。
$mech-&gt;submit_form(
    fields =&gt; {
        email =&gt; 'your-email@example.com',
        password =&gt; 'p4ssw0rd',
    },
);
$mech-&gt;get('http://mixi.jp/home.pl');

# 足あとページに遷移
$mech-&gt;get('http://mixi.jp/show_log.pl');

print $mech-&gt;content;
</code></pre>

<p>ちなみに Mixi 用は <a href="http://search.cpan.org/perldoc?WWW::Mixi">WWW::Mixi</a> という専用モジュールもあります。<a href="http://search.cpan.org/perldoc?Plagger">Plagger</a> にもプラグインがあります。Plagger については、またいずれ。。.</p>

<h4>定時打刻</h4>

<p>もっと<em>黒い</em>使い方だと、Desknet's のようなウェブアプリで出退勤管理している会社の場合..</p>

<pre><code>my $mech = new WWW::Mechanize( autocheck =&gt; 1 );

# ここでは NEOJAPAN 社のデモサイトを使わせてもらいます。
$mech-&gt;get('http://www.desknets.com/standard/product/demo/');
$mech-&gt;follow_link(url_regex =&gt; qr{/cgi-bin/demo/dnet/dnet.cgi});

# ログインし...
$mech-&gt;submit_form(
    fields =&gt; {
        uid  =&gt; 2, # 山田太郎
       _word =&gt; '',
        save =&gt; 1,
    },
);

# 出勤！
$mech-&gt;submit_form(
    button =&gt; 's_go',
);
</code></pre>

<p>これを cron にしこめば。。。あ、ぼくはやってるわけじゃありません。あくまで例です！ 笑</p>

<p>実際にやったお遊びな例では、</p>

<h4>出前館でピザを取る</h4>

<p><a href="http://e8y.net/repos/Plagger-Plugin-Notify-Pizza/trunk/lib/Plagger/Plugin/Notify/Pizza.pm">このファイルを参照</a>。出前館というサイトにログイン → 適当なピザを選択 → 注文までを実行しています。こんなこともできますよ、という例として。</p>

<p>あとこの時は、<a href="http://search.cpan.org/perldoc?HTTP::Recorder">HTTP::Recorder</a> というモジュールを使い、ブラウザの操作を自動で Mech スクリプトとして記録させる、という面白いこともやっています。<a href="http://e8y.net/blog/2006/07/25/p126.html">当時のエントリ</a>の下のほうに書いていますので、興味のある方はご覧ください。 </p>

<h3>JavaScript</h3>

<p>さて、遊びだけではなく、ウェブアプリケーションのテストモジュールといったまじめな用途にも向いてます。これは、<a href="http://search.cpan.org/perldoc?Test::WWW::Mechanize">Test::WWW::Mechanize</a> としてテストモジュール化されています。</p>

<p>ただ、Mech は賢いのですが JavaScript の動作はエミュレートしません。なので、Ajax 部分などクライアント側のテストには向いていません。</p>

<p>クライアント側の挙動のテストを行なうには、実際のブラウザのエンジンを使うのが一番でしょう。これは、<a href="http://www.openqa.org/selenium/">Selenium</a> というウェブアプリテストスイートがあります。</p>

<p>Selenium コアは JavaScript によるアプリですが、ドメインをまたげない制限を回避するソリューションとして、プロキシサーバーとして動作する Selenium RC という Java アプリも用意されています。そのプロキシサーバーに対しては各種プログラミング言語から直接テストをたたく API が用意されていますが、Perl 用も <a href="http://search.cpan.org/perldoc?WWW::Selenium">WWW::Selenium</a> として CPAN にあります。</p>

<p>Mech については、文字コードまわりやファイルのダウンロード＆保存など、まだ話は尽きませんが、関連モジュールを扱うときなどにまた取り上げようと思います。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?WWW::Mechanize">WWW::Mechanize</a>, <a href="http://perldoc.jp/docs/modules/WWW-Mechanize-1.02/Mechanize.pod">WWW::Mechanize 和訳</a> <br />
和訳のあるモジュールについては和訳のリンクも載せることにしました。ただ、CPAN モジュールの英語はコードが間に入るのでそんなに難しくないので挑戦してみてください。Mech のドキュメントはわかりやすいお手本のような英語です。</p>

<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873111870/ele-22/ref=nosim/">Spidering hacks</a> という本には、Mech を使ったサンプルが多数載っています。 <br />
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873111870/ele-22/ref=nosim/"><img style="border: medium none ;" src="http://images-jp.amazon.com/images/P/4873111870.09.MZZZZZZZ.jpg" alt="Spidering hacks―ウェブ情報ラクラク取得テクニック101選"></a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-18T21:03:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/006-cpan-mini/">
    <title>use CPAN::Mini;</title>
    <link>http://e8y.net/mag/006-cpan-mini/</link>
    <description>これまで、軽めのモジュールを何個か取り上げてきましたが、「なんだこんなもんか」とナメられても困るので、次回あたりからそろそろ気合を入れ大型モジュールを取り上げようかと思います。 それに先立って、CPANモジュールを全部ローカルに落としておくといいです。  大型モジュールは依存モジュールも相当ありますが、全部ローカルにあればインストールが当然超ー速いです。今回はそれをするためのモジュールの話です。 http://www.cpan.org/ の右上に現在の CPAN モジュールの総数、サイズが出ています。1995年から10年以上にわたって蓄積され続けている CPAN モジュールですが、現時点で 1...</description>
    <content:encoded><![CDATA[<p>これまで、軽めのモジュールを何個か取り上げてきましたが、「なんだこんなもんか」とナメられても困るので、次回あたりからそろそろ気合を入れ大型モジュールを取り上げようかと思います。</p>

<p>それに先立って、<em>CPANモジュールを全部ローカルに</em>落としておくといいです。 </p>

<p>大型モジュールは依存モジュールも相当ありますが、全部ローカルにあればインストールが当然超ー速いです。今回はそれをするためのモジュールの話です。</p>

<p><a href="http://www.cpan.org/">http://www.cpan.org/</a> の右上に現在の CPAN モジュールの総数、サイズが出ています。1995年から10年以上にわたって蓄積され続けている CPAN モジュールですが、現時点で 10,000 強のモジュール、総容量 3.5GB 程度あるらしいです。ただし、各モジュールの最新版だけ集めると、実は660MB程度です。まだ CD 1枚に入るんです。</p>

<p><a href="http://search.cpan.org/perldoc?CPAN::Mini"><em>CPAN::Mini</em></a> というモジュールがその最新版全部の一括ダウンロード・更新管理をしてくれます。まずは CPAN::Mini をインストールしてください。CPAN::Mini を入れると、（<a href="http://e8y.net/mag/005-module-corelist/">昨日</a>の corelist のように） <em><code>minicpan</code></em> というコマンドがいっしょに入ります。</p>

<p>こうやって使います。</p>

<pre><code>&gt; minicpan -r http://ftp.cpan.jp/ -l ~/minicpan
</code></pre>

<p>これで、リモートの http://ftp.cpan.jp/ から、ローカルのホームディレクトリに minicpan というディレクトリを作り、そこに一式ダウンロードを開始します。リモートサイトは<a href="http://www.cpan.org/SITES.html#Asia">CPANミラーの他のサイト</a>でもOKです。ftp.cpan.jp は落ちてることが多い気がします。</p>

<p>ネットワーク状況にもよりますが、初回だけは30分?1時間くらいかかると思います。2回目以降は、新規追加・更新があったモジュールだけ入りますので、すぐ終わります。</p>

<p>完成したら、cron などでこのコマンドが1日1回とか動くようにしておくとよいです。-q をつけるとエラー以外は出力されないのでそうするとよいでしょう。 </p>

<pre><code>0 3 * * * minicpan -q -r http://ftp.cpan.jp/ -l ~/minicpan
</code></pre>

<p>次に、この ~/minicpan からインストールするように cpan 側を設定します。~/minicpan が /home/tomi/minicpan な場合は、</p>

<pre><code>$ su
# cpan
cpan&gt; o conf prerequisites_policy follow
cpan&gt; o conf urllist unshift file:///home/tomi/minicpan
cpan&gt; o conf
cpan&gt; o conf commit
cpan&gt; q
</code></pre>

<p>こんなかんじで、ローカルの ~/minicpan を優先できます。</p>

<p><code>o conf prerequisites_policy follow</code> は、依存モジュールがあった時の 「インストールしますか？ [Y/n]」 みたいなとき、自動で Y を選ぶ、というオプションです。 </p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?CPAN::Mini">CPAN::Mini</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-16T04:01:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/005-module-corelist/">
    <title>use Module::CoreList;</title>
    <link>http://e8y.net/mag/005-module-corelist/</link>
    <description><![CDATA[ぜんぜん日刊じゃないじゃないか！と言われそうなので、こっそり発行周期を「ほぼ日刊」に改めた今日のCPANモジュールです。 さて、前々回の Fatal は、“コア”モジュールでした。つまり、Perlと一緒に入ってくるので別途インストールが不要なモジュールです。前回の App::Options は、コアじゃないのでインストール（&gt; sudo cpan App::Options）が必要です。 あるモジュールが、コアなのかコアじゃないのか、また Perl のバージョンいくつからバンドルされているのか、そのあたりを調べることができるのが Module::CoreList です。 インストールすると...]]></description>
    <content:encoded><![CDATA[<p>ぜんぜん日刊じゃないじゃないか！と言われそうなので、こっそり発行周期を「ほぼ日刊」に改めた今日のCPANモジュールです。</p>

<p>さて、前々回の Fatal は、“コア”モジュールでした。つまり、Perlと一緒に入ってくるので別途インストールが不要なモジュールです。前回の App::Options は、コアじゃないのでインストール（<code>&gt; sudo cpan App::Options</code>）が必要です。</p>

<p>あるモジュールが、コアなのかコアじゃないのか、また Perl のバージョンいくつからバンドルされているのか、そのあたりを調べることができるのが <a href="http://search.cpan.org/dist/Module-CoreList/"><em>Module::CoreList</em></a> です。</p>

<p>インストールすると、<em>corelist</em> というプログラムが /usr/local/bin などパスの通ったところにインストールされます。 </p>

<p>使い方は、corelist に聞きたいモジュール名を渡すだけです。 </p>

<pre><code>&gt; corelist Fatal

Fatal  was first released with perl 5.00307
</code></pre>

<p>Fatal は Perl 5.3 のころからコアであることがわかります。</p>

<p>ほかに、例えば <a href="http://search.cpan.org/perldoc?CGI">CGI</a> というモジュールはコアなのですが、バージョン3.06で文字コードまわりの動作変更がありました。そこで、最近の Perl にはバージョン何がバンドルされてるのかな、と調べるときは -a を使います。</p>

<pre><code>&gt; corelist -a CGI

CGI  was first released with perl 5.004
  5.004      2.36      
  5.00405    2.42      
  5.005      2.42      
  5.00503    2.46      
  5.00504    2.46      
  5.006      2.56      
  5.006001   2.752     
  5.006002   2.752     
  5.007003   2.80      
  5.008      2.81      
  5.008001   3.00      
  5.008002   3.00      
  5.008003   3.01      
  5.008004   3.04      
  5.008005   3.05      
  5.008006   3.05      
  5.008007   3.10      
  5.008008   3.15      
  5.009      3.00      
  5.009001   3.04      
  5.009002   3.07      
  5.009003   3.15_01
</code></pre>

<p>と、Perl 5.8.7 から 3.06 以上が入っていることがわかります。ちなみに、点2個を使うバージョン表記を小数表記すると 5.8.6 = 5.008006 です。</p>

<p>corelist に聞くモジュール名は大文字小文字正しい必要がありますが、よくわからないときは正規表現風に スラッシュではさんで渡すとそう解釈してくれます。さて、Module::CoreList そのものはコアでしょうか？ </p>

<pre><code>&gt; corelist /::corelist/i

Module::CoreList  was first released with perl 5.009002
</code></pre>

<p>perl 5.9.2 から、ということですね。5.8 系の場合は corelist を使う前に <code>cpan Module::Corelist</code> する必要があります。</p>

<p>Perl では、この点2個形式で真ん中の数字が<em>偶数＝正式リリース</em>、<em>奇数＝開発版</em>という意味で、5.9.x は 5.10 へ向けての開発版ということです。つまり、Module::CoreList は 5.10 から晴れてコア入りするらしいことがわかります。</p>

<p>他のオプションは、corelist --help するか、<a href="http://search.cpan.org/perldoc?corelist">PODを参照</a>してください。 </p>

<p>Module::CoreList のように、インストールすると、そのモジュール自身を使った小さなプログラムをインストールしてくれるタイプのはけっこうたくさんあります。<a href="http://search.cpan.org/perldoc?App::Ack">App::Ack</a> の <a href="http://search.cpan.org/perldoc?ack">ack</a> とか、<a href="http://search.cpan.org/perldoc?LWP">LWP</a> の GET や HEAD など。いずれとりあげます。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?Module::CoreList">Module::CoreList</a>, <a href="http://search.cpan.org/perldoc?corelist">corelist</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-15T04:32:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/004-app-options/">
    <title>use App::Options;</title>
    <link>http://e8y.net/mag/004-app-options/</link>
    <description>コマンドライン型プログラムで、引数を受け取る部分の話題です。たとえば、 hoge.pl --name=&quot;Tomita Naoki&quot; --age=28 --debug というように引数を指定した場合、プログラム側では name が &quot;Tomita Naoki&quot;、debug は true というように受け取りたいわけです。 受け取るだけじゃなく、こんな要件もあろうかと思います。  name と age は必須にしたい age は数字だけ受け取れるように name のデフォルト値は Unknown に --help が指定された場合は Usage を表示して終わる GetOptions + pod2...</description>
    <content:encoded><![CDATA[<p>コマンドライン型プログラムで、引数を受け取る部分の話題です。たとえば、</p>

<pre><code>hoge.pl --name="Tomita Naoki" --age=28 --debug
</code></pre>

<p>というように引数を指定した場合、プログラム側では name が <code>"Tomita Naoki"</code>、debug は <code>true</code> というように受け取りたいわけです。</p>

<p>受け取るだけじゃなく、こんな要件もあろうかと思います。 </p>

<ul>
<li>name と age は必須にしたい</li>
<li>age は数字だけ受け取れるように</li>
<li>name のデフォルト値は Unknown に</li>
<li>--help が指定された場合は Usage を表示して終わる</li>
</ul>

<h3>GetOptions + pod2usage を使う方法</h3>

<p>このとき、よく使われて、かつ悪くないのは、<a href="http://search.cpan.org/perldoc?Getopt::Long">Getopt::Long</a> と <a href="http://search.cpan.org/perldoc?Pod::Usage">Pod::Usage</a> の組み合わせです。Getopt::Long まわりは幾つかの書き方がありますが、こんな感じです。</p>

<pre><code>use Getopt::Long;
use Pod::Usage;

my %argv = (
    name =&gt; 'Unknown',
    age  =&gt; '',
);

GetOptions(
    \%argv,
    "name=s",
    "age=i",
    "debug",
    "help",
) or $argv{help}++;

pod2usage(2) if $argv{help};

# 処理...
print "Hello $argv{name}.
</code></pre>

<p>";</p>

<pre><code>=head1 SYNOPSIS

使い方...

=cut
</code></pre>

<p>この GetOptions + pod2usage の組み合わせがいいのは、両方ともコアモジュールだという点です。しかし、CPAN には上記例をもっと簡単便利に書けるモジュールが超たくさんあります。</p>

<h3>App::Options を使う方法</h3>

<p>中でもぼくのお気に入りは <a href="http://search.cpan.org/perldoc?App::Options"><em>App::Options</em></a> です。 <br />
これだと上の例がこうなります。</p>

<pre><code>use App::Options(
    option =&gt; {
        name  =&gt; "type=string; required; default=Unknown;",
        age   =&gt; "type=integer;",
        debug =&gt; "type=boolean",
    },
);

# 値は %App::options ハッシュの中に入ります
print "Hello $App::options{name}.
</code></pre>

<p>";</p>

<p>use 文の中ですべてまとまっていることや、シンプルで直感的なのでお気に入りです。</p>

<p>いちおうほかの引数取得系モジュールで琴線にふれたものをメルマガの最後の SEE ALSO に並べておきますので、以下の説明で App::Options にひかれない人は別なのも見てみてください。</p>

<p>賢いのが<em>自動 Usege 機能</em>で、特に指示しなくても <code>--help</code> の時や必須条件をクリアしなかった場合に自動で Usage を表示してくれます。 </p>

<pre><code>&gt; test.pl --age="twenty eight" --name=Tomita

Error: "age" must be of type "integer" (not "twenty eight")
Usage: test.pl [options] [args]
       --help                             print this message (also -?)
       --age=&lt;value&gt;                      [twenty eight] (integer)
       --debug                            [undef] (boolean)
       --name=&lt;value&gt;                     [Tomita] (string)
</code></pre>

<p>お気に入りなのですが、日本語での説明を見かけないモジュールなので、少し詳しく解説していきます。</p>

<h4>option =></h4>

<p>use App::Options に渡す option という引数にはコマンドラインから取得するキーと、その値の条件を書いていきます。条件は、セミコロンで区切って以下のような各種指示を書けます。</p>

<ul>
<li><p><em><code>type=...;</code></em> として、例で使った string、integer、boolean 以外に、float、date（YYYY-MM-DD形式）、time（HH:MM:SS形式）、datetime（YYYY-MM-DD HH:MM:SS形式）が選べます。日付系は便利です。それ以外の場合は、</p>

<pre><code>use App::Options(
    option =&gt; {
        gender =&gt; 'type=/^(male|female)$/; required;',
    },
);
</code></pre>

<p>と正規表現で指定したりできます。</p></li>
<li><em><code>required;</code></em> もしくは <code>required=1;</code> で「必須」です。</li>
<li><em><code>default=...;</code></em> にデフォルトの値を指定できます。</li>
<li><em><code>env=...;</code></em> というのもあって、コマンドライン引数じゃなく任意の環境変数から値をとるようにする指示を書けます、これも便利なのですが、環境変数の話をまだしてなかったので後で説明します。</li>
</ul>

<p>使うのは こんなとこですが、ほかのもあげると、<code>description=...;</code> や <code>value_description=...;</code> を指示すると、自動 Usage 表記をカスタマイズできます。セミコロン区切りの文字列ではなく、ハッシュで渡すこともできます。 </p>

<pre><code>use App::Options(
    option =&gt; {
        name =&gt; {
            type =&gt; 'string',
            required =&gt; 1,
            default =&gt; 'Unknown',
        },
        age =&gt; {
            type =&gt; 'integer',
        },
    },
);
</code></pre>

<h4>values =></h4>

<p>use App::Options のところで渡せるオプションには option 以外にいろいろあって、便利なのが values です。デフォルトだと App::Options は <code>%App::options</code> ハッシュ（oが小文字なのに注意）に値を入れていきますが、これを変えることができます。`$App::options{なんとか}" だとちょっと長い？ということでそれを短い %argv にしたい場合はこうです。</p>

<pre><code>my %argv;
use App::Options (
    values =&gt; \%argv,
    option =&gt; {
        name  =&gt; "type=string;",
    },
);

# $App::options{name} ではなく、
print "Hello $argv{name}.
</code></pre>

<p>";</p>

<p>短縮化を進むなら <code>%ARGV</code> を使うのもおすすめです。<code>%ARGV</code> は Perl が使う変数ではありませんが、<code>@ARGV</code> などが予約されている関係で、use strict; 下でも my とか our 宣言しないで使える抜け道です。</p>

<pre><code>use App::Options (
    values =&gt; \%ARGV,
);

print "Hello $ARGV{name}.
</code></pre>

<p>";</p>

<h4>print_usage =></h4>

<p>App::Options の自動 Usage が気に入らない場合は、print_usage にサブルーチンを渡すことで置き換えることができます。例えばヘルプは Pod::Usage を使って POD の SYNOPSIS を出したいよ、という場合は以下のようにします。</p>

<pre><code>use Pod::Usage;
use App::Options (
    print_usage =&gt; sub { pod2usage(2) },
);

=head1 SYNOPSIS

test.pl --date=2006-02-28

brah brah brah brah brah brah...

=cut
</code></pre>

<p>App::Options の自動 Usage <em>も</em>出したいよ、という場合にはデフォルトのも呼び出せばいいです。</p>

<pre><code>use Pod::Usage;
use App::Options (
    values =&gt; \%ARGV,
    option =&gt; {
        debug =&gt; "type=date",
    },
    print_usage =&gt; sub { 
        App::Options-&gt;print_usage(@_);
        pod2usage(2);
    },
);

=head1 SYNOPSIS

test.pl --date=2006-02-28

brah brah brah brah brah brah...

=cut
</code></pre>

<p>さて、書くのが疲れてきました。くわしくは <a href="http://search.cpan.org/perldoc?App::Options">POD</a> を眺めるとだいたいわかると思うのででそろそろ終わりにします。（POD = Perl のソースコード内に書かれるドキュメント形式。ドキュメントという意味で使われることも。）</p>

<h3>デフォルトで行われる処理</h3>

<p>ただ、App::Options はただ引数処理をするだけではなく、もっと大きな野望をもったモジュールだ、というのを覚えておく必要があります。それがゆえに、ただ引数を取りたいという目的だけだとちょっと余計とも思える動作をします。</p>

<p><em>App::</em> というかっこいい名前空間は、P5EE - Perl 5 Enterprise Environment Project で使われていて、大規模なアプリケーション用モジュールを見越したモジュール用とされています。App::Options もそのファミリーであり、いろいろ考えているわけです。どうもP5EE プロジェクトそのものはあまり盛り上がっていないように見えますが、ストップしているわけではありませんし、複数メンバーで全体を見ているようなので、わりと安心して使い続けられます。</p>

<p>まず、<em>コマンドラインで指定しなくても、app, host, prefix, hostname というキーが自動的に設定</em>されます。たとえば app には、ファイル名が test.pl の場合、test という値が入ります。</p>

<p>さらに実は App::Options は、コマンドラインからの引数と環境変数からの値と ini 形式のファイルからの値をブレンドするという機能があり、それが自動で働きます。（<code>no_env_vars =&gt; 1;</code> や <code>no_option_file =&gt; 1;</code> を use App::Options に渡すことでそちらは無視させることが可能）</p>

<p>環境変数は、APP_なんとか に値を指定しておくと、「--なんとか」の代わりとして使えます。あと option の env 指示でまったく別な環境変数を読ませることもできます。</p>

<p>ini 形式のファイルを読む機能はなかなか高度で、この順番で設定ファイルを探す機能や、プロダクション環境用とステージング環境用の値を書いておいて、app の値でどちらかを選ぶ、などが実装されています。</p>

<p>最近は YAML で設定を書くことが多いので、ぼくはこの機能はほとんど使わず、App::Options を引数の処理だけに使うことが多いです。メンテナーの Stephen に聞いたところ、将来 ini 形式だけじゃなくて、YAML などに対応する予定もあるよ、ということだったので、期待してます。 </p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?App::Options">App::Options</a>, <a href="http://search.cpan.org/perldoc?Getopt::Long">Getopt::Long</a>, <a href="http://search.cpan.org/perldoc?Pod::Usage">Pod::Usage</a> <br />
<a href="http://search.cpan.org/perldoc?Getopt::Casual">Getopt::Casual</a>, <a href="http://search.cpan.org/perldoc?Getopt::Euclid">Getopt::Euclid</a>, <a href="http://search.cpan.org/perldoc?Scriptalicious">Scriptalicious</a>, <a href="http://search.cpan.org/perldoc?Script::Toolbox">Script::Toolbox</a>, <a href="http://search.cpan.org/perldoc?Getopt::Auto">Getopt::Auto</a>, <a href="http://search.cpan.org/perldoc?App::CLI">App::CLI</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-08T05:56:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/003-fatal/">
    <title>use Fatal;</title>
    <link>http://e8y.net/mag/003-fatal/</link>
    <description><![CDATA[ファイルを開いてごにょごにょする処理はありがちですが、以下のようなサンプルを見かけることがあります。 $file = "file.txt"; open FH, "&lt; $file" or die "Can't open $file: $!"; while (&lt;FH&gt;) {     # 処理... } close FH or die "Close $file failed: $!"; open や close は、失敗したときに undef を返すので、エラー処理のため or die が2回入ってますが、この何個も並ぶ or die を書かなくてよくなるちょいと便利なモジュールが...]]></description>
    <content:encoded><![CDATA[<p>ファイルを開いてごにょごにょする処理はありがちですが、以下のようなサンプルを見かけることがあります。</p>

<pre><code>$file = "file.txt";
open FH, "&lt; $file" or die "Can't open $file: $!";
while (&lt;FH&gt;) {
    # 処理...
}
close FH or die "Close $file failed: $!";
</code></pre>

<p>open や close は、失敗したときに undef を返すので、エラー処理のため <code>or die</code> が2回入ってますが、この<em>何個も並ぶ <code>or die</code> を書かなくてよくなる</em>ちょいと便利なモジュールが <a href="http://search.cpan.org/perldoc?Fatal"><em>Fatal</em></a> です。上の例はこんな感じになります。</p>

<pre><code>use Fatal qw(open close);

my $file = "file.txt";

open my $fh, '&lt;', $file;
while (&lt;$fh&gt;) {
    # ...
}
close $fh;
</code></pre>

<p>Fatal が、渡されたサブルーチン（上の例だと open と close） をくるんで、自動で or die してくれます。open や close がだいぶすっきりしました。あとついでに先ほどの例に対してファイルハンドルを変数にしたり open を3引数にと今風に変更してみてあります。</p>

<p>Fatal は Perl 5.00307 以降コアモジュールなので、たいていはどこでも最初から入っています。エラー処理をしつつ、コードもすっきりするのでおすすめです。</p>

<h3>:void</h3>

<p>一個オプションがあって、<em>:void</em> という特別な名前を渡して use すると、先ほどの例のようなものは普通に Fatal するのですが、if 文の中にあるような、返り値が評価される場合にはたとえ undef が返ってきたとしても Fatal しなくなります。</p>

<pre><code>use Fatal qw( :void open );

if ( open my $fh, '&lt;', $file ) { # Fatalしない
    # 自分で処理を書きたい場合
}

open my $fh, '&lt;', $file; # Fatalする
</code></pre>

<p>ぼくはもっぱら open と close にしか使ってないですが、</p>

<pre><code>use Imager;
use Fatal qw( Imager::read );

my $img = Imager-&gt;new;
$img-&gt;read(file =&gt; "dummy");
</code></pre>

<p>ていう風に他モジュールのサブルーチンを Fatal 化したり、</p>

<pre><code>sub foo {

}

use Fatal qw( foo );
foo();
</code></pre>

<p>みたいに自作のルーチンを Fatal 化するのも一応可能です。どちらも、Fatal が use される前にサブルーチンが宣言されている必要ありですが。あんまりやらないですね。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?Fatal">Fatal</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-07T03:28:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/002-strict/">
    <title>use strict;</title>
    <link>http://e8y.net/mag/002-strict/</link>
    <description>まあこれは、お気に入りというより、基本なので最初にとりあげておきます。 SYNOPSIS use strict; my $hello = &quot;こんにちは&quot;; print &quot;$helo &quot;; # エラー 使い方は簡単で、スクリプトの最初で普通に use するだけです。  効果としては、上の例のように、宣言してない変数を使った場合（Typoした時とか）などにコンパイルエラーとなります。 Perl は最初は「賢いシェルスクリプト」といった感じでしたが、その過去のバージョンとの互換をたいへん重視して進化してきたため、strict しない状態だとかなりゆるい言語です。が、use strict した Per...</description>
    <content:encoded><![CDATA[<p>まあこれは、お気に入りというより、基本なので最初にとりあげておきます。</p>

<h3>SYNOPSIS</h3>

<pre><code>use strict;

my $hello = "こんにちは";
print "$helo
</code></pre>

<p>"; # エラー</p>

<p>使い方は簡単で、スクリプトの最初で普通に use するだけです。 <br />
効果としては、上の例のように、宣言してない変数を使った場合（Typoした時とか）などにコンパイルエラーとなります。</p>

<p>Perl は最初は「賢いシェルスクリプト」といった感じでしたが、その過去のバージョンとの互換をたいへん重視して進化してきたため、strict しない状態だとかなりゆるい言語です。が、use strict した Perl は LL（Lightweight Language） の中でもかなり厳しい言語仕様を身につけます。</p>

<p>使い方のイメージとしては、strict が便利だから、というよりも、<em>さあ始めるかっ！</em> 的にまずは use strict; を書き入れる感じです。</p>

<p>よく strict に並んで use warnings も並列して上げられ、それも書いておいて間違いはないですが、strict の方がより重要です。モジュールを書く時は、デバッグ時に perl -w したなどの理由で、モジュールそのものには use warnings を書かないケースもあります。</p>

<p>でも use strict は絶対です。use strict されてないモジュールは、作者の品格が疑われる位の扱いです。笑</p>

<p>こういった Perl 紹介系の本・雑誌・メルマガで、どれくらい最初の方で strict に触れるかで内容が見極められてしまうとも思うので、2回目で忘れずに紹介しておきます。 </p>

<p>ちなみにこういった小文字から初まるモジュールをプラグマモジュールと呼びます。コンパイル時に影響を及ぼすモジュールという意味です。</p>

<p>次回からは普通にお気に入りのモジュールを適当に紹介していきます。 </p>

<h3>SEE ALSO</h3>

<p><a href="http://perldoc.perl.org/strict.html">strict</a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-02-06T03:09:00+09:00</dc:date>
</item>
<item rdf:about="http://e8y.net/mag/001-cpan/">
    <title>use CPAN;</title>
    <link>http://e8y.net/mag/001-cpan/</link>
    <description>なかなか身近に Perl 好きが現れないなあ・・と思い、 とつぜんですが、メルマガを始めてみることにしました。この時代にメルマガ！？というのも面白いかと。 Perl の面白さは CPAN モジュール にあります。 PHP、Python、Java、Ruby といろいろさわって来ましたが、他の言語に比べ Perl のライブラリ（モジュール）は仕事の範囲が小さく多岐に及んでいる、という特徴がある気がします。  つまり、細かい部品を組み合わせてものを作るというイメージです。その部品は CPAN に1万以上あるのですが、これだけあると最初はなかなかとっつきにくいです。また、CPAN が発達した理由には玉...</description>
    <content:encoded><![CDATA[<p>なかなか身近に Perl 好きが現れないなあ・・と思い、 とつぜんですが、メルマガを始めてみることにしました。この時代にメルマガ！？というのも面白いかと。</p>

<p>Perl の面白さは <em>CPAN モジュール</em> にあります。</p>

<p>PHP、Python、Java、Ruby といろいろさわって来ましたが、他の言語に比べ Perl のライブラリ（モジュール）は仕事の範囲が小さく多岐に及んでいる、という特徴がある気がします。 </p>

<p>つまり、細かい部品を組み合わせてものを作るというイメージです。その部品は <a href="http://search.cpan.org/">CPAN</a> に1万以上あるのですが、これだけあると最初はなかなかとっつきにくいです。また、CPAN が発達した理由には玉石混合を認めるという文化があるのです（だからいろんなのがあっておもしろい）が、最初は「どれが玉？」というのもあると思います。</p>

<p>このメルマガでは、「これはおすすめ」というものや、「最近達人たちが注目してるのはこれ」てなモジュールを1回1個形式でお届け。冨田の私見ですが。とりあえずは1日1個ペースでいける・・と思います。</p>

<p>第一回目は最初なので そのまま <a href="http://search.cpan.org/perldoc?CPAN"><em>CPAN</em></a> というモジュールです。 </p>

<p>CPAN は <em>C</em>omprehensive <em>P</em>erl <em>A</em>rchive <em>N</em>etwork の略で、Perl そのものやモジュール郡を保管してあるサイト（プロジェクト）の名前です。 <br />
<a href="http://www.cpan.org/">http://www.cpan.org/</a> （モジュールの検索ページは <a href="http://search.cpan.org/">http://search.cpan.org/</a>）</p>

<h3>cpan</h3>

<p>そのモジュール郡は tar.gz 形式でUPされており、linux 系でインストールするには、</p>

<pre><code>wget http://search.cpan.org/../Hoge-Hoge-0.01.tar.gz # ダウンロードして
tar zxvf Hoge-Hoge-0.01.tar.gz  # 解凍、
cd Hoge-Hoge-0.01
perl Makefile.PL  # これで make コマンド用ファイルが作成される
make          # あとは普通のプログラム的に make で
make test
sudo make install
</code></pre>

<p>が基本的な形です。</p>

<p>で、上記ダウンロード?インストールまでを簡略化するためのモジュールがあり、その名も CPAN です。CPAN は Perl が入ってたらすでに入ってると思いますが、入ってない場合は<a href="http://search.cpan.org/dist/CPAN/">ここから</a>落としてきて、上記手順で <code>make install</code> すると入ります。</p>

<p>インストールされると、cpan というコマンドも入ります。これが、ダウンロードからインストールまでやってくれるものです。</p>

<pre><code>$ su
# cpan
cpan&gt;              # cpanシェルに入る
cpan&gt; install Hoge::Hoge
cpan&gt; q
</code></pre>

<p>最初いろいろ聞かれますが、ネットワークにつながったマシンなら適当ーに Enter でいいはずです。</p>

<p>もしくは、</p>

<pre><code># cpan Hoge::Hoge
</code></pre>

<p>とか</p>

<pre><code>$ sudo cpan Hoge::Hoge
</code></pre>

<p>これでもOKです。 <br />
こんな感じで cpan コマンドを使えるなら、続く号もすぐ試せて面白いと思います。</p>

<h3>SEE ALSO</h3>

<p><a href="http://search.cpan.org/perldoc?CPAN">CPAN</a></p>

<p><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844322893/ele-22/ref=nosim/">まるごとPerl</a>はとっかかりの部分が比較的丁寧に説明されています。 <br />
<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844322893/ele-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/31122XTWW7L.jpg" alt="まるごとPerl! Vol.1" style="border: none;" /></a></p>
]]></content:encoded>
    <dc:subject></dc:subject>
    <dc:creator>tomita</dc:creator>
    <dc:date>2007-01-27T22:24:53+09:00</dc:date>
</item>

</rdf:RDF>