Changeset 27033

Show
Ignore:
Timestamp:
12/18/08 23:59:19 (4 years ago)
Author:
otsune
Message:

Update RSS feed

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • websites/perl-users.jp/html/articles/advent-calendar/adventcal.rss

    r26833 r27033  
    55    <link>http://perl-users.jp/articles/advent-calendar/2008/</link> 
    66    <title>JPerl Advent Calendar 2008</title> 
    7     <pubDate>Tue, 16 Dec 2008 08:59:37 +0900</pubDate> 
     7    <pubDate>Thu, 18 Dec 2008 23:56:31 +0900</pubDate> 
    88    <item> 
    99      <author>nobody@example.com</author> 
     
    1515-e syntax OK「sub foo() { }」のように書くと、この関数が引数をとらないことを宣言できます。この関数が定数を返す場合、この関数は定数として展開されます。 
    1616</description> 
    17       <dc:date>2008-12-05T03:45:03Z</dc:date> 
     17      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    1818      <title>定数の展開</title> 
    19       <pubDate>Fri, 05 Dec 2008 03:45:03 -0000</pubDate> 
     19      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    2020      <content:encoded>&lt;body&gt;&lt;h1&gt;定数の展開&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;% perl -MO=Deparse,-print -e&amp;apos;sub foo() { 0 }; warn foo&amp;apos; 
    2121sub foo () { 0 } 
     
    2323-e syntax OK&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;「&lt;code&gt;sub foo() { }&lt;/code&gt;」のように書くと、この関数が引数をとらないことを宣言できます。&lt;/p&gt;&lt;p&gt;この関数が定数を返す場合、この関数は定数として展開されます。&lt;/p&gt;&lt;/body&gt; 
    2424</content:encoded> 
    25       <dcterms:modified>2008-12-05T03:45:03Z</dcterms:modified> 
     25      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    2626      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/01.html</guid> 
    2727    </item> 
     
    4444he is soffritto「\my $vars」と書く事により変数の定義をしつつ戻り値で、その定義した変数のリファレンスを返す。よって、関数の引数に「\my $xxx」と書くとコンパクトに書ける。が、これはTTくらいでしか使ってるの見た事無い。つぎのバトンはid:lestrratさん。 
    4545</description> 
    46       <dc:date>2008-12-05T03:45:03Z</dc:date> 
     46      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    4747      <title>myのリファレンス</title> 
    48       <pubDate>Fri, 05 Dec 2008 03:45:03 -0000</pubDate> 
     48      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    4949      <content:encoded>&lt;body&gt;&lt;h1&gt;myのリファレンス&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;$ cat cool.pl 
    5050use strict; 
     
    6161he is soffritto&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;「&lt;code&gt;\my $vars&lt;/code&gt;」と書く事により変数の定義をしつつ戻り値で、その定義した変数のリファレンスを返す。&lt;/p&gt;&lt;p&gt;よって、関数の引数に「&lt;code&gt;\my $xxx&lt;/code&gt;」と書くとコンパクトに書ける。&lt;/p&gt;&lt;p&gt;が、これは&lt;abbr title="Template Toolkit"&gt;TT&lt;/abbr&gt;くらいでしか使ってるの見た事無い。&lt;/p&gt;&lt;p&gt;つぎのバトンはid:lestrratさん。&lt;/p&gt;&lt;/body&gt; 
    6262</content:encoded> 
    63       <dcterms:modified>2008-12-05T03:45:03Z</dcterms:modified> 
     63      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    6464      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/02.html</guid> 
    6565    </item> 
     
    9494    }なお、全てのeval{}でこの処理を加える必要はありませんが、該当する箇所にエラーがあってもわざとそれを無視する今回のような場合には明示的にlocalをつけておいたほうが安全です。次はid:hidekさん 
    9595</description> 
    96       <dc:date>2008-12-07T09:21:35Z</dc:date> 
     96      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    9797      <title>$@はグローバル変数</title> 
    98       <pubDate>Sun, 07 Dec 2008 09:21:35 -0000</pubDate> 
    99       <content:encoded>&lt;body&gt;&lt;h1&gt;$@はグローバル変数&lt;/h1&gt;&lt;p&gt;あまり意識されていませんが、&lt;code&gt;$@&lt;/code&gt;はグローバル変数です。気をつけないとおかしなことになります。以下のコードでは&lt;code&gt;die()&lt;/code&gt;で例外を発生させているので「&lt;samp&gt;Error is Dummy error&lt;/samp&gt;」と表示されるように見えますが、表示されません。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    package Hoge; 
     98      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
     99      <content:encoded>&lt;body&gt;&lt;h1&gt;$@はグローバル変数&lt;/h1&gt;&lt;p&gt;あまり意識されていませんが、&lt;code&gt;$@&lt;/code&gt;はグローバル変数です。気をつけないとおかしなことになります。以下のコードでは&lt;code&gt;die()&lt;/code&gt;で例外を発生させているので「&lt;samp&gt;Error is Dummy error&lt;/samp&gt;」と表示されるように見えますが、表示されません。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    package Hoge; 
    100100    sub new { bless {}, shift } 
    101101    sub cleanup { 
     
    117117    } else { 
    118118        print &amp;quot;Everything OK!\n&amp;quot;; 
    119     }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;eval&lt;/code&gt;が&lt;code&gt;die()&lt;/code&gt;によって終了し、スコープが切り替わる段階で&lt;code&gt;DESTROY&lt;/code&gt;が呼ばれます。その中で&lt;code&gt;eval{}&lt;/code&gt;をもう一度呼んでいますが、ここではエラーがなかったため&lt;code&gt;$@&lt;/code&gt;が空に設定されるのです。よって、エラーの値を出力するころにはすでに&lt;code&gt;$@&lt;/code&gt;は空で、エラーを検知できません。&lt;/p&gt;&lt;p&gt;このようなグローバル変数を変更する可能性のあるコードを書く場合は&lt;code&gt;local&lt;/code&gt;で修飾すると良いでしょう。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    sub DESTROY { 
     119    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;eval&lt;/code&gt;が&lt;code&gt;die()&lt;/code&gt;によって終了し、スコープが切り替わる段階で&lt;code&gt;DESTROY&lt;/code&gt;が呼ばれます。その中で&lt;code&gt;eval{}&lt;/code&gt;をもう一度呼んでいますが、ここではエラーがなかったため&lt;code&gt;$@&lt;/code&gt;が空に設定されるのです。よって、エラーの値を出力するころにはすでに&lt;code&gt;$@&lt;/code&gt;は空で、エラーを検知できません。&lt;/p&gt;&lt;p&gt;このようなグローバル変数を変更する可能性のあるコードを書く場合は&lt;code&gt;local&lt;/code&gt;で修飾すると良いでしょう。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    sub DESTROY { 
    120120        my $self = shift; 
    121121        local $@; 
     
    123123    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;なお、全ての&lt;code&gt;eval{}&lt;/code&gt;でこの処理を加える必要はありませんが、該当する箇所にエラーがあってもわざとそれを無視する今回のような場合には明示的に&lt;code&gt;local&lt;/code&gt;をつけておいたほうが安全です。&lt;/p&gt;&lt;p&gt;次はid:hidekさん&lt;/p&gt;&lt;/body&gt; 
    124124</content:encoded> 
    125       <dcterms:modified>2008-12-07T09:21:35Z</dcterms:modified> 
     125      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    126126      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/03.html</guid> 
    127127    </item> 
     
    156156    my $scalar_ref = anon_scalar('a');と書くことも出来ます次はid:hirose31さん 
    157157</description> 
    158       <dc:date>2008-12-07T09:21:35Z</dc:date> 
     158      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    159159      <title>無名スカラー変数のリファレンス</title> 
    160       <pubDate>Sun, 07 Dec 2008 09:21:35 -0000</pubDate> 
    161       <content:encoded>&lt;body&gt;&lt;h1&gt;無名スカラー変数のリファレンス&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;    my $array_ref = [qw/a b c/]; 
     160      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
     161      <content:encoded>&lt;body&gt;&lt;h1&gt;無名スカラー変数のリファレンス&lt;/h1&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    my $array_ref = [qw/a b c/]; 
    162162    my $hash_ref = +{1 =&amp;gt; &amp;apos;a&amp;apos;, 2 =&amp;gt; &amp;apos;b&amp;apos;, 3 =&amp;gt; &amp;apos;c&amp;apos;}; 
    163     my $code_ref = sub {&amp;apos;a&amp;apos;};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; Perlでは、無名配列のリファレンス 無名ハッシュのリファレンス、無名サブルーチンのリファレンスはこのように書けますが、無名スカラーのリファレンスを書く特別な構文はないので、以下のように書きます。 &lt;/p&gt;&lt;pre&gt;&lt;code&gt;    my $scalar_ref = \do {&amp;apos;a&amp;apos;};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; これはDamian Conway先生オススメのインサイドアウトオブジェクトのコンストラクタで見られる書き方です。 &lt;/p&gt;&lt;pre&gt;&lt;code&gt;    { 
     163    my $code_ref = sub {&amp;apos;a&amp;apos;};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; Perlでは、無名配列のリファレンス 無名ハッシュのリファレンス、無名サブルーチンのリファレンスはこのように書けますが、無名スカラーのリファレンスを書く特別な構文はないので、以下のように書きます。 &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    my $scalar_ref = \do {&amp;apos;a&amp;apos;};&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; これはDamian Conway先生オススメのインサイドアウトオブジェクトのコンストラクタで見られる書き方です。 &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    { 
    164164        package Person; 
    165165        my %props = (); 
     
    179179    # $person-&amp;gt;{name} = &amp;apos;Tom&amp;apos;; #エラー 
    180180    $person-&amp;gt;name(&amp;apos;Tom&amp;apos;); 
    181     warn $person-&amp;gt;name; # Tom&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; こうすることによってスカラーをバックエンドとするオブジェクトを作ることができ、オブジェクトのカプセル化をすることができます。 &lt;/p&gt;&lt;p&gt;さらにid:tokuhiromさんの指摘で &lt;/p&gt;&lt;pre&gt;&lt;code&gt;    my $scalar_ref = \&amp;apos;a&amp;apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;でもよいことを知りました。&lt;/p&gt;&lt;p&gt;ただしこの場合はimmutableされて変更ができなくなるので先ほどの例では「&lt;samp&gt;Modification of a read-only value&lt;/samp&gt;」とエラーになります。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Template-&amp;gt;new-&amp;gt;process(\&amp;apos;[% foo %]&amp;apos;, {foo =&amp;gt; 3})&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;とかでも使うそうです。&lt;/p&gt;&lt;p&gt;typseterさんに指摘されて思い出しましたが、そういえばDBICでも使いますね。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    select =&amp;gt; [ 
     181    warn $person-&amp;gt;name; # Tom&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; こうすることによってスカラーをバックエンドとするオブジェクトを作ることができ、オブジェクトのカプセル化をすることができます。 &lt;/p&gt;&lt;p&gt;さらにid:tokuhiromさんの指摘で &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    my $scalar_ref = \&amp;apos;a&amp;apos;;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;でもよいことを知りました。&lt;/p&gt;&lt;p&gt;ただしこの場合はimmutableされて変更ができなくなるので先ほどの例では「&lt;samp&gt;Modification of a read-only value&lt;/samp&gt;」とエラーになります。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;Template-&amp;gt;new-&amp;gt;process(\&amp;apos;[% foo %]&amp;apos;, {foo =&amp;gt; 3})&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;とかでも使うそうです。&lt;/p&gt;&lt;p&gt;typseterさんに指摘されて思い出しましたが、そういえばDBICでも使いますね。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    select =&amp;gt; [ 
    182182        \&amp;quot;date_trunc (&amp;apos;day&amp;apos;, created_on) as created_day&amp;quot;, 
    183183        { count =&amp;gt; &amp;apos;id&amp;apos; } 
    184     ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;または音速のXS使いid:gfxさんのData::Utilを使うと&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    use Data::Util qw(anon_scalar); 
     184    ]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;または音速のXS使いid:gfxさんのData::Utilを使うと&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;    use Data::Util qw(anon_scalar); 
    185185    my $scalar_ref = anon_scalar(&amp;apos;a&amp;apos;);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;と書くことも出来ます&lt;/p&gt;&lt;p&gt;次はid:hirose31さん&lt;/p&gt;&lt;/body&gt; 
    186186</content:encoded> 
    187       <dcterms:modified>2008-12-07T09:21:35Z</dcterms:modified> 
     187      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    188188      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/04.html</guid> 
    189189    </item> 
     
    2232234  &lt;@&gt; leave[1 ref] vKP/REFC というわけでopcodeでたった3つ分だけ効率的です。 次はid:typesterさん 
    224224</description> 
    225       <dc:date>2008-12-07T09:21:35Z</dc:date> 
     225      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    226226      <title>効率的な変数宣言</title> 
    227       <pubDate>Sun, 07 Dec 2008 09:21:35 -0000</pubDate> 
     227      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    228228      <content:encoded>&lt;body&gt;&lt;h1&gt;効率的な変数宣言&lt;/h1&gt;&lt;p&gt;&lt;code&gt;my %hash=();&lt;/code&gt;より&lt;code&gt;my %hash;&lt;/code&gt;の方が効率的です。 &lt;/p&gt;&lt;p&gt; どのぐらい効率的かというと: &lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perl -MO=Concise -e &amp;apos;my %hash=()&amp;apos; 
    2292297  &amp;lt;@&amp;gt; leave[1 ref] vKP/REFC -&amp;gt;(end) 
     
    2572574  &amp;lt;@&amp;gt; leave[1 ref] vKP/REFC&lt;code&gt;&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; というわけでopcodeでたった3つ分だけ効率的です。 &lt;/p&gt;&lt;p&gt;次はid:typesterさん&lt;/p&gt;&lt;/body&gt; 
    258258</content:encoded> 
    259       <dcterms:modified>2008-12-07T09:21:35Z</dcterms:modified> 
     259      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    260260      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/05.html</guid> 
    261261    </item> 
     
    269269などのように書くことも出来るようになっているそうです。次は dann さん。 
    270270</description> 
    271       <dc:date>2008-12-06T10:19:09Z</dc:date> 
     271      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    272272      <title>ファイルテスト演算子をつかいまくる</title> 
    273       <pubDate>Sat, 06 Dec 2008 10:19:09 -0000</pubDate> 
     273      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    274274      <content:encoded>&lt;body&gt;&lt;h1&gt;ファイルテスト演算子をつかいまくる&lt;/h1&gt;&lt;p&gt;&lt;code&gt;_&lt;/code&gt; という特殊変数があり、これは最後にテスト演算子に渡した引数を示します。&lt;/p&gt;&lt;p&gt;よって、ファイルでありかつリーダブルでありかつ実行可能であるというようなテストをしたい場合は、&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-f $file &amp;amp;&amp;amp; -r $file &amp;amp;&amp;amp; -x $file; 
    275275&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;とするかわりに、&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-f $file &amp;amp;&amp;amp; -r _ &amp;amp;&amp;amp; -x _; 
     
    277277&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;などのように書くことも出来るようになっているそうです。&lt;/p&gt;&lt;p&gt;次は dann さん。&lt;/p&gt;&lt;/body&gt; 
    278278</content:encoded> 
    279       <dcterms:modified>2008-12-06T10:19:09Z</dcterms:modified> 
     279      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    280280      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/06.html</guid> 
    281281    </item> 
     
    318318コマンドラインスイッチは、perldoc perlrunで調べられます。他にも便利なコマンドラインスイッチや特殊変数があるので、是非読んでみてください次は yusukebe さん。 
    319319</description> 
    320       <dc:date>2008-12-06T16:53:17Z</dc:date> 
     320      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    321321      <title>コマンドラインスイッチと特殊変数を使いまくる</title> 
    322       <pubDate>Sat, 06 Dec 2008 16:53:17 -0000</pubDate> 
     322      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    323323      <content:encoded>&lt;body&gt;&lt;h1&gt;コマンドラインスイッチと特殊変数を使いまくる&lt;/h1&gt;&lt;p&gt;ファイルの奇数行だけを表示したいといったときに、例えばどんなコードを書くでしょうか。&lt;/p&gt;&lt;p&gt;例えば、以下のように書く事ができます。&lt;/p&gt;&lt;pre&gt; 
    324324&lt;code&gt; 
     
    355355&lt;/pre&gt;&lt;p&gt;コマンドラインスイッチは、perldoc perlrunで調べられます。&lt;/p&gt;&lt;p&gt;他にも便利なコマンドラインスイッチや特殊変数があるので、是非読んでみてください&lt;/p&gt;&lt;p&gt;次は yusukebe さん。&lt;/p&gt;&lt;/body&gt; 
    356356</content:encoded> 
    357       <dcterms:modified>2008-12-06T16:53:17Z</dcterms:modified> 
     357      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    358358      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/07.html</guid> 
    359359    </item> 
     
    380380 こんな感じで使えます。  ./dl.pl http://metiss.blog92.fc2.com/blog-entry-142.html  Tipsというより便利スクリプトの紹介になってしまいしたことご了承くだされ。 さて、次のバトンは _33rpm さんに渡します。  
    381381</description> 
    382       <dc:date>2008-12-08T14:55:47Z</dc:date> 
     382      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    383383      <title>ワンライナーで画像収集</title> 
    384       <pubDate>Mon, 08 Dec 2008 14:55:47 -0000</pubDate> 
     384      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    385385      <content:encoded>&lt;body&gt;&lt;h1&gt;ワンライナーで画像収集&lt;/h1&gt;&lt;p&gt;某掲示板まとめブログのエッチな記事に載っている画像を収集したいときに、Perl ではワンライナー、つまり1行のコマンドで書くことができます。例えば、女の子の太もも画像 ( http://metiss.blog92.fc2.com/blog-entry-142.html ) にリンクされている画像をカレントディレクトリにダウンロードしたければ以下のようなコマンドをたたくだけです。&lt;/p&gt;&lt;pre&gt; 
    386386&lt;code&gt; 
     
    401401&lt;/pre&gt;&lt;p&gt; こんな感じで使えます。 &lt;/p&gt;&lt;code&gt; ./dl.pl http://metiss.blog92.fc2.com/blog-entry-142.html &lt;/code&gt;&lt;p&gt; Tipsというより便利スクリプトの紹介になってしまいしたことご了承くだされ。 さて、次のバトンは _33rpm さんに渡します。 &lt;/p&gt;&lt;/body&gt; 
    402402</content:encoded> 
    403       <dcterms:modified>2008-12-08T14:55:47Z</dcterms:modified> 
     403      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    404404      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/08.html</guid> 
    405405    </item> 
     
    450450 こんな書き方も出来ます。さて、次のバトンは nekokak さんに渡します。  
    451451</description> 
    452       <dc:date>2008-12-09T05:49:01Z</dc:date> 
     452      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    453453      <title>全てのコードにテストを(標準入力乗っ取り編)</title> 
    454       <pubDate>Tue, 09 Dec 2008 05:49:01 -0000</pubDate> 
     454      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    455455      <content:encoded>&lt;body&gt;&lt;h1&gt;全てのコードにテストを(標準入力乗っ取り編)&lt;/h1&gt;&lt;p&gt; テストコード書くのってピタゴラ装置作るみたいで楽しいですよね。 というわけであらゆるコードにはテストコードを用意してあげたい! けどそういうときちょっとめんどくさいのが、昔ながらのCGIスクリプトやメールフィルタなどのフィルタスクリプト、要はSTDINからデータが入ってくる前提のコードです。 make testやproveからテストする前提だと標準入力に何も渡さないし…、 というわけでこんなかんじでテストを書いてみます。 &lt;/p&gt;&lt;pre&gt; 
    456456&lt;code&gt; 
     
    495495&lt;/pre&gt;&lt;p&gt; こんな書き方も出来ます。さて、次のバトンは nekokak さんに渡します。 &lt;/p&gt;&lt;/body&gt; 
    496496</content:encoded> 
    497       <dcterms:modified>2008-12-09T05:49:01Z</dcterms:modified> 
     497      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    498498      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/09.html</guid> 
    499499    </item> 
     
    532532このようにファイルを指定せずに書けば、unlinkも必要なく、ゴミファイルが残る心配もありませんね。次は zigorou さん。 
    533533</description> 
    534       <dc:date>2008-12-09T16:14:48Z</dc:date> 
     534      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    535535      <title>SQLiteを使ったテストのtips</title> 
    536       <pubDate>Tue, 09 Dec 2008 16:14:48 -0000</pubDate> 
     536      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
    537537      <content:encoded>&lt;body&gt;&lt;h1&gt;SQLiteを使ったテストのtips&lt;/h1&gt;&lt;p&gt;DB周りのモジュールを開発している場合、テストDBにSQLiteを使う事が良くあります。&lt;/p&gt;&lt;p&gt;その際、普通であれば以下のようなテストコードを書くと思います&lt;/p&gt;&lt;pre&gt;&lt;code&gt;use Test::More tests =&amp;gt; 1; 
    538538use DBI; 
     
    565565&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このようにファイルを指定せずに書けば、unlinkも必要なく、ゴミファイルが残る心配もありませんね。&lt;/p&gt;&lt;p&gt;次は zigorou さん。&lt;/p&gt;&lt;/body&gt; 
    566566</content:encoded> 
    567       <dcterms:modified>2008-12-09T16:14:48Z</dcterms:modified> 
     567      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    568568      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/10.html</guid> 
    569569    </item> 
     
    612612 のような形になります。またエラーハンドリングの package 名に対する正規表現によるグルーピングもできます。詳しくは perldoc Carp::Clan を見て下さい。  次は id:kazuhooku さん。  
    613613</description> 
    614       <dc:date>2008-12-15T00:29:28Z</dc:date> 
     614      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    615615      <title>Carp::Clan でエラーハンドリングのススメ</title> 
    616       <pubDate>Mon, 15 Dec 2008 00:29:28 -0000</pubDate> 
     616      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
    617617      <content:encoded>&lt;body&gt;&lt;h1&gt;Carp::Clan でエラーハンドリングのススメ&lt;/h1&gt;&lt;div class="section"&gt;&lt;h2&gt;Carp, Carp::Clan で共通のこと&lt;/h2&gt;&lt;dl&gt;&lt;dt&gt;carp&lt;/dt&gt;&lt;dd&gt;呼び出し元の分かる warn&lt;/dd&gt;&lt;dt&gt;cluck&lt;/dt&gt;&lt;dd&gt;carp + stack backtrace&lt;/dd&gt;&lt;dt&gt;croak&lt;/dt&gt;&lt;dd&gt;呼び出し元の分かる die&lt;/dd&gt;&lt;dt&gt;confess&lt;/dt&gt;&lt;dd&gt;croak + stack backtrace&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;但し Carp の場合は &lt;var&gt;cluck&lt;/var&gt; や &lt;var&gt;confess&lt;/var&gt; を明示的に使うよりも、&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perl -MCarp=verbose target.pl 
    618 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt; という使い方でも stacktrace を得ることが出来ます。Carp::Clan の場合は、 &lt;/p&gt;&lt;pre&gt;&lt;code&gt;use Carp::Clan; 
     618&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; という使い方でも stacktrace を得ることが出来ます。Carp::Clan の場合は、 &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use Carp::Clan; 
    619619 
    620620$Carp::Clan::Verbose = 1 if $ENV{DEBUG}; 
     
    623623$ perl carp_clan.pl 
    624624NS::A::do_a(): warning message!!! at carp_clan.pl line 19 
    625 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt; という具合です。具体的なコードでは、 &lt;/p&gt;&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl 
     625&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; という具合です。具体的なコードでは、 &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;#!/usr/bin/perl 
    626626 
    627627use strict; 
     
    655655&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; のような形になります。またエラーハンドリングの package 名に対する正規表現によるグルーピングもできます。詳しくは perldoc Carp::Clan を見て下さい。 &lt;/p&gt;&lt;p&gt; 次は id:kazuhooku さん。 &lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
    656656</content:encoded> 
    657       <dcterms:modified>2008-12-15T00:29:28Z</dcterms:modified> 
     657      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    658658      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/11.html</guid> 
    659659    </item> 
     
    671671これなら、不要な変数に頭を悩まされずに1ステートメントで書くことができ、意味も明快です。いいですね。次は id:amachang。 
    672672</description> 
    673       <dc:date>2008-12-11T03:51:21Z</dc:date> 
     673      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    674674      <title>非破壊な s/// のススメ</title> 
    675       <pubDate>Thu, 11 Dec 2008 03:51:21 -0000</pubDate> 
    676       <content:encoded>&lt;body&gt;&lt;h1&gt;非破壊な s/// のススメ&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;正規表現の置換でときどき困るのは、元の文字列が変更されてしまうことです。そのため、たとえば文字列を URI escape する際には、以下のように別変数にコピーした上で、正規表現を適用することになります。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my $escaped = $search_str; 
     675      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
     676      <content:encoded>&lt;body&gt;&lt;h1&gt;非破壊な s/// のススメ&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;正規表現の置換でときどき困るのは、元の文字列が変更されてしまうことです。そのため、たとえば文字列を URI escape する際には、以下のように別変数にコピーした上で、正規表現を適用することになります。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my $escaped = $search_str; 
    677677$escaped =~ s/([^0-9A-Za-z_.!~*&amp;apos;()-])/&amp;apos;%&amp;apos; . uc(unpack(&amp;apos;H2&amp;apos;, $1))/eg; 
    678678my $url = &amp;quot;http://example.com/search?q=$escaped&amp;quot;; 
    679 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以前、&lt;a href="http://labs.cybozu.co.jp/blog/kazuho/archives/2007/07/perl_ndes_regex.php"&gt;この点がめんどくさいなーとブログに書いた&lt;/a&gt;ところ、kazeburo さん他に以下のようなテクニックを教えていただきました。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;use List::MoreUtils qw(apply); 
     679&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以前、&lt;a href="http://labs.cybozu.co.jp/blog/kazuho/archives/2007/07/perl_ndes_regex.php"&gt;この点がめんどくさいなーとブログに書いた&lt;/a&gt;ところ、kazeburo さん他に以下のようなテクニックを教えていただきました。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use List::MoreUtils qw(apply); 
    680680 
    681681my $url = &amp;apos;http://example.com/search?q=&amp;apos; 
     
    683683&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これなら、不要な変数に頭を悩まされずに1ステートメントで書くことができ、意味も明快です。いいですね。&lt;/p&gt;&lt;p&gt;次は id:amachang。&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
    684684</content:encoded> 
    685       <dcterms:modified>2008-12-11T03:51:21Z</dcterms:modified> 
     685      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    686686      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/12.html</guid> 
    687687    </item> 
     
    11641164         
    11651165</description> 
    1166       <dc:date>2008-12-15T00:29:28Z</dc:date> 
     1166      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    11671167      <title>Win32::GuiTest で Windows の GUI アプリをハックしよう</title> 
    1168       <pubDate>Mon, 15 Dec 2008 00:29:28 -0000</pubDate> 
    1169       <content:encoded>&lt;body&gt;&lt;h1&gt;Win32::GuiTest で Windows の GUI アプリをハックしよう&lt;/h1&gt;&lt;p&gt; どうも&lt;a href="http://d.hatena.ne.jp/amachang/"&gt;あまちゃん&lt;/a&gt;です。 突然ですが、 Win32::GuiTest というモジュールを使うと Windows の GUI アプリを楽しくハックする事ができます。 &lt;/p&gt;&lt;p&gt; 使う側は特にめんどうくさいことをしなくても (時には別プロセスに入り込んで)様々な情報を取得してきたり設定してきたりしてくれます。 &lt;/p&gt;&lt;div&gt;&lt;h2&gt;インストール&lt;/h2&gt;&lt;p&gt;&lt;a href="http://strawberryperl.com/"&gt;Strawberry Perl&lt;/a&gt; を使っているなら普通に &lt;pre&gt;&lt;code&gt;C:\&amp;gt; cpan -i Win32::GuiTest 
    1170 &lt;/code&gt;&lt;/pre&gt; でインストールできます。 &lt;a href="http://www.activestate.com/Products/activeperl/index.mhtml"&gt;ActivePerl&lt;/a&gt; を使っている場合は、&lt;a href="http://sourceforge.net/projects/winguitest"&gt;PPM があります&lt;/a&gt;。 &lt;/p&gt;&lt;/div&gt;&lt;div class="step"&gt;&lt;h2&gt;ケーススタディ&lt;/h2&gt;&lt;p&gt; ソースはコピペすれば動くと思いますよっと。UTF-8 で書いてます。 &lt;/p&gt;&lt;div id="toc"&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;基本的な書き方&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1168      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
     1169      <content:encoded>&lt;body&gt;&lt;h1&gt;Win32::GuiTest で Windows の GUI アプリをハックしよう&lt;/h1&gt;&lt;p&gt; どうも&lt;a href="http://d.hatena.ne.jp/amachang/"&gt;あまちゃん&lt;/a&gt;です。 突然ですが、 Win32::GuiTest というモジュールを使うと Windows の GUI アプリを楽しくハックする事ができます。 &lt;/p&gt;&lt;p&gt; 使う側は特にめんどうくさいことをしなくても (時には別プロセスに入り込んで)様々な情報を取得してきたり設定してきたりしてくれます。 &lt;/p&gt;&lt;div&gt;&lt;h2&gt;インストール&lt;/h2&gt;&lt;p&gt;&lt;a href="http://strawberryperl.com/"&gt;Strawberry Perl&lt;/a&gt; を使っているなら普通に &lt;/p&gt;&lt;pre&gt;&lt;code&gt;C:\&amp;gt; cpan -i Win32::GuiTest 
     1170&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; でインストールできます。 &lt;a href="http://www.activestate.com/Products/activeperl/index.mhtml"&gt;ActivePerl&lt;/a&gt; を使っている場合は、&lt;a href="http://sourceforge.net/projects/winguitest"&gt;PPM があります&lt;/a&gt;。 &lt;/p&gt;&lt;/div&gt;&lt;div class="step"&gt;&lt;h2&gt;ケーススタディ&lt;/h2&gt;&lt;p&gt; ソースはコピペすれば動くと思いますよっと。UTF-8 で書いてます。 &lt;/p&gt;&lt;div id="toc"&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;基本的な書き方&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    11711171use warnings; 
    11721172use utf8; 
     
    11801180 
    11811181# ここで Win32::GuiTest を使う 
    1182 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;マウスを動かす&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1182&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;マウスを動かす&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    11831183use warnings; 
    11841184use utf8; 
     
    11991199    MouseMoveAbsPix(cos($i / 10) * 400 + 400, sin($i / 10) * 400 + 400); 
    12001200} 
    1201 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;デスクトップ領域を取得する&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1201&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;デスクトップ領域を取得する&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    12021202use warnings; 
    12031203use utf8; 
     
    12261226    ); 
    12271227} 
    1228 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;全ウィンドウの列挙&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1228&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;全ウィンドウの列挙&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    12291229use warnings; 
    12301230use utf8; 
     
    12461246    # ここで各ウィンドウ($child)にあんなことやこんなことをする 
    12471247} 
    1248 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ウィンドウの情報を取得&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1248&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ウィンドウの情報を取得&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    12491249use warnings; 
    12501250use utf8; 
     
    12751275    print $cp932-&amp;gt;encode(&amp;apos;--&amp;apos; x $window_depth . $window_text . &amp;apos;(&amp;apos; . $class_name . &amp;quot;)\n&amp;quot;); 
    12761276} 
    1277 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211163602"&gt;&lt;img alt="20081211163602" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211163602.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ウィンドウ名からウィンドウを取得&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1277&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211163602"&gt;&lt;img alt="20081211163602" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211163602.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ウィンドウ名からウィンドウを取得&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    12781278use warnings; 
    12791279use utf8; 
     
    12931293# 情報の表示 
    12941294print $cp932-&amp;gt;encode(GetWindowText($win) . &amp;apos;(&amp;apos; . GetClassName($win) . &amp;quot;)\n&amp;quot;); 
    1295 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211164830"&gt;&lt;img alt="20081211164830" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211164830.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;Button をクリックさせる&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1295&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211164830"&gt;&lt;img alt="20081211164830" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211164830.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;Button をクリックさせる&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    12961296use warnings; 
    12971297use utf8; 
     
    13161316# FindWindowLike から SendLButton*() までを一発でやってくれる 
    13171317# MouseClick という関数もありますが、今回は使いません 
    1318 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211170226"&gt;&lt;img alt="20081211170226" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211170226.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;メニューの取得&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1318&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211170226"&gt;&lt;img alt="20081211170226" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211170226.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;メニューの取得&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    13191319use warnings; 
    13201320use utf8; 
     
    13611361 
    13621362})-&amp;gt;(GetMenu($notepad), 0); # メモ帳のメインメニューを渡す 
    1363 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211184621"&gt;&lt;img alt="20081211184621" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211184621.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;メニューの選択&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1363&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211184621"&gt;&lt;img alt="20081211184621" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211184621.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;メニューの選択&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    13641364use warnings; 
    13651365use utf8; 
     
    13871387# しかも、フルの名前を指定しないといけないので、めんどうです。 
    13881388# 今回は使いません>< 
    1389 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190920"&gt;&lt;img alt="20081211190920" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190920.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスへ文字を入力する(1)&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1389&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190920"&gt;&lt;img alt="20081211190920" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190920.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスへ文字を入力する(1)&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    13901390use warnings; 
    13911391use utf8; 
     
    14081408# WMSetText を使って、エディットボックスの値を直接設定 
    14091409WMSetText($edit, $cp932-&amp;gt;encode(&amp;apos;ほげほげ&amp;apos;)); 
    1410 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190921"&gt;&lt;img alt="20081211190921" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190921.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスへ文字を入力する(2)(キーボード入力をエミュレート)&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1410&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190921"&gt;&lt;img alt="20081211190921" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190921.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスへ文字を入力する(2)(キーボード入力をエミュレート)&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    14111411use warnings; 
    14121412use utf8; 
     
    14301430# キーボード入力をエミュレート 
    14311431SendKeys(&amp;apos;hoge{ENTER}hoge{ENTER}fuga{ENTER}piyo&amp;apos;); 
    1432 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190922"&gt;&lt;img alt="20081211190922" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190922.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスの文字を取得する&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1432&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190922"&gt;&lt;img alt="20081211190922" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190922.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;エディットボックスの文字を取得する&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    14331433use warnings; 
    14341434use utf8; 
     
    14511451# (CP932 で帰ってくるので、そのまま print してるけど、プログラム中で扱う時は decode すべき) 
    14521452print WMGetText($edit) . &amp;quot;\n&amp;quot;; 
    1453 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190923"&gt;&lt;img alt="20081211190923" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190923.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ツリービューを選択する&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1453&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081211190923"&gt;&lt;img alt="20081211190923" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081211/20081211190923.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ツリービューを選択する&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    14541454use warnings; 
    14551455use utf8; 
     
    14821482 
    14831483# この関数は、エクスプローラーでも威力を発揮します。 
    1484 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081212005253"&gt;&lt;img alt="20081212005253" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081212/20081212005253.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;リストビューのアイテムをダブルクリックする&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1484&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081212005253"&gt;&lt;img alt="20081212005253" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081212/20081212005253.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;リストビューのアイテムをダブルクリックする&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    14851485use warnings; 
    14861486use utf8; 
     
    15591559# この例のように、 
    15601560# 自分で共有メモリ(AllocateVirtualBuffer)を使って生のメッセージでやるというパターンは結構あります。 
    1561 &lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081212020713"&gt;&lt;img alt="20081212020713" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081212/20081212020713.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ツールバーをクリックする&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;use strict; 
     1561&lt;/code&gt;&lt;/pre&gt; &lt;a href="http://f.hatena.ne.jp/amachang/20081212020713"&gt;&lt;img alt="20081212020713" src="http://img.f.hatena.ne.jp/images/fotolife/a/amachang/20081212/20081212020713.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;ツールバーをクリックする&lt;/h3&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
    15621562use warnings; 
    15631563use utf8; 
     
    16411641        &lt;/script&gt;&lt;/body&gt; 
    16421642</content:encoded> 
    1643       <dcterms:modified>2008-12-15T00:29:28Z</dcterms:modified> 
     1643      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    16441644      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/13.html</guid> 
    16451645    </item> 
     
    17001700実行結果:BBB:BBC:XXX:B次は国内滞在説が根強い id:miyagawa さんにお願いしたいと思います。;-) 
    17011701</description> 
    1702       <dc:date>2008-12-15T02:23:17Z</dc:date> 
     1702      <dc:date>2008-12-16T13:43:19Z</dc:date> 
    17031703      <title>ヒアドキュメントの中でPerlの式を書く</title> 
    1704       <pubDate>Mon, 15 Dec 2008 02:23:17 -0000</pubDate> 
    1705       <content:encoded>&lt;body&gt;&lt;h1&gt;ヒアドキュメントの中でPerlの式を書く&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;&lt;a href="http://news.google.co.jp/news?hl=ja&amp;amp;q=%E6%96%B0%E5%B9%B9%E7%B7%9A&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;ncl=1259980833&amp;amp;sa=X&amp;amp;oi=news_result&amp;amp;resnum=1&amp;amp;ct=more-results&amp;amp;cd=1"&gt;初代新幹線「0系」最後のラストランの日&lt;/a&gt;に、新幹線N700系のぞみでイーモバイルしながらこの記事を書いている&lt;a href="http://namazu.org/~takesako/"&gt;id:TAKESAKO&lt;/a&gt;です。&lt;/p&gt;&lt;p&gt;Perlのヒアドキュメントを使うと複数行にわたる文字列を一気に代入したりするときに楽なので、使っている人も多いと思います。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my $foo = &amp;quot;bar&amp;quot;; 
     1704      <pubDate>Tue, 16 Dec 2008 13:43:19 -0000</pubDate> 
     1705      <content:encoded>&lt;body&gt;&lt;h1&gt;ヒアドキュメントの中でPerlの式を書く&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;&lt;a href="http://news.google.co.jp/news?hl=ja&amp;amp;q=%E6%96%B0%E5%B9%B9%E7%B7%9A&amp;amp;um=1&amp;amp;ie=UTF-8&amp;amp;ncl=1259980833&amp;amp;sa=X&amp;amp;oi=news_result&amp;amp;resnum=1&amp;amp;ct=more-results&amp;amp;cd=1"&gt;初代新幹線「0系」最後のラストランの日&lt;/a&gt;に、新幹線N700系のぞみでイーモバイルしながらこの記事を書いている&lt;a href="http://namazu.org/~takesako/"&gt;id:TAKESAKO&lt;/a&gt;です。&lt;/p&gt;&lt;p&gt;Perlのヒアドキュメントを使うと複数行にわたる文字列を一気に代入したりするときに楽なので、使っている人も多いと思います。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my $foo = &amp;quot;bar&amp;quot;; 
    17061706my $tmp = time(); # ←関数の実行結果 
    17071707print&amp;lt;&amp;lt;EOF; 
     
    17101710  &amp;lt;/div&amp;gt; 
    17111711EOF 
    1712 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;しかし、ヒアドキュメントの途中でサブルーチンの実行結果も一緒に埋め込みたいときがでてくるときがあります。&lt;/p&gt;&lt;h2&gt;@{[ Perlの式 ]}&lt;/h2&gt;&lt;p&gt;そのようなときは、&lt;code&gt;@{[ リスト ]}&lt;/code&gt; というイディオムを使うと非常に便利です。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
     1712&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;しかし、ヒアドキュメントの途中でサブルーチンの実行結果も一緒に埋め込みたいときがでてくるときがあります。&lt;/p&gt;&lt;h2&gt;@{[ Perlの式 ]}&lt;/h2&gt;&lt;p&gt;そのようなときは、&lt;code&gt;@{[ リスト ]}&lt;/code&gt; というイディオムを使うと非常に便利です。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
    17131713  &amp;lt;div class=&amp;quot;${foo}1&amp;quot;&amp;gt; 
    17141714    &amp;lt;h1&amp;gt;TIME: @{[ time() ]}&amp;lt;/h1&amp;gt; 
    17151715  &amp;lt;/div&amp;gt; 
    17161716EOF 
    1717 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar1&amp;quot;&amp;gt; 
     1717&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar1&amp;quot;&amp;gt; 
    17181718    &amp;lt;h1&amp;gt;TIME: 1229258525&amp;lt;/h1&amp;gt; 
    17191719  &amp;lt;/div&amp;gt; 
    1720 &lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;@{[ リスト ]} の中にはPerlの式をそのまま書くことができます。&lt;/p&gt;&lt;p&gt;この例では、関数 time() の実行結果がヒアドキュメントの文字列の中に埋め込まれていることがわかります。&lt;/p&gt;&lt;h3&gt;リストコンテキストの罠&lt;/h3&gt;&lt;p&gt;しかし、このイディオムの式はリストコンテキストで評価されるので、wantarray でサブルーチンの戻り値を切り替えている関数などでは期待通りの結果が得られない場合があります。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
     1720&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;@{[ リスト ]} の中にはPerlの式をそのまま書くことができます。&lt;/p&gt;&lt;p&gt;この例では、関数 time() の実行結果がヒアドキュメントの文字列の中に埋め込まれていることがわかります。&lt;/p&gt;&lt;h3&gt;リストコンテキストの罠&lt;/h3&gt;&lt;p&gt;しかし、このイディオムの式はリストコンテキストで評価されるので、wantarray でサブルーチンの戻り値を切り替えている関数などでは期待通りの結果が得られない場合があります。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
    17211721  &amp;lt;div class=&amp;quot;${foo}2&amp;quot;&amp;gt; 
    17221722    &amp;lt;h1&amp;gt;TIME: @{[ localtime() ]}&amp;lt;/h1&amp;gt; 
    17231723  &amp;lt;/div&amp;gt; 
    17241724EOF 
    1725 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar2&amp;quot;&amp;gt; 
     1725&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar2&amp;quot;&amp;gt; 
    17261726    &amp;lt;h1&amp;gt;TIME: 5 42 21 14 11 108 0 348 0&amp;lt;/h1&amp;gt; 
    17271727  &amp;lt;/div&amp;gt; 
    1728 &lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;このような場合は、式が必ずスカラーコンテキストで評価されるように、 &lt;code&gt;&amp;quot;&amp;quot;.localtime()&lt;/code&gt; もしくは &lt;code&gt;scalar localtime()&lt;/code&gt; などと記述すれば大丈夫です。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
     1728&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;このような場合は、式が必ずスカラーコンテキストで評価されるように、 &lt;code&gt;&amp;quot;&amp;quot;.localtime()&lt;/code&gt; もしくは &lt;code&gt;scalar localtime()&lt;/code&gt; などと記述すれば大丈夫です。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print&amp;lt;&amp;lt;EOF; 
    17291729  &amp;lt;div class=&amp;quot;${foo}3&amp;quot;&amp;gt; 
    17301730    &amp;lt;h1&amp;gt;TIME: @{[ scalar localtime() ]}&amp;lt;/h1&amp;gt; 
    17311731  &amp;lt;/div&amp;gt; 
    17321732EOF 
    1733 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar3&amp;quot;&amp;gt; 
     1733&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;  &amp;lt;div class=&amp;quot;bar3&amp;quot;&amp;gt; 
    17341734    &amp;lt;h1&amp;gt;TIME: Sun Dec 14 21:42:05 2008&amp;lt;/h1&amp;gt; 
    17351735  &amp;lt;/div&amp;gt; 
    1736 &lt;/samp&gt;&lt;/pre&gt;&lt;h3&gt;&amp;quot;@a\n&amp;quot; と特殊変数 $&amp;quot;&lt;/h3&gt;&lt;p&gt;ちなみに、ダブルクォート文字列中に &lt;code&gt;@a&lt;/code&gt; を埋め込んだ場合、例えば &lt;code&gt;&amp;quot;@a\n&amp;quot;&lt;/code&gt; は &lt;code&gt;join($&amp;quot;,@a).&amp;quot;\n&amp;quot;&lt;/code&gt; と等価となります。&lt;/p&gt;&lt;p&gt;&lt;code&gt;$&amp;quot;&lt;/code&gt; は、配列のリストを文字列に変換するときに自動的に要素間に挿入する文字列(デフォルトは空白 &lt;code&gt;&amp;quot; &amp;quot;&lt;/code&gt;)を意味する特殊変数です。&lt;br /&gt; 一時的に &lt;code&gt;$&amp;quot;&lt;/code&gt; の値を書き換えて、要素間に自動挿入する文字列をデフォルトの空白から任意の文字列に変更することもできます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;do { 
     1736&lt;/samp&gt;&lt;/pre&gt;&lt;h3&gt;&amp;quot;@a\n&amp;quot; と特殊変数 $&amp;quot;&lt;/h3&gt;&lt;p&gt;ちなみに、ダブルクォート文字列中に &lt;code&gt;@a&lt;/code&gt; を埋め込んだ場合、例えば &lt;code&gt;&amp;quot;@a\n&amp;quot;&lt;/code&gt; は &lt;code&gt;join($&amp;quot;,@a).&amp;quot;\n&amp;quot;&lt;/code&gt; と等価となります。&lt;/p&gt;&lt;p&gt;&lt;code&gt;$&amp;quot;&lt;/code&gt; は、配列のリストを文字列に変換するときに自動的に要素間に挿入する文字列(デフォルトは空白 &lt;code&gt;&amp;quot; &amp;quot;&lt;/code&gt;)を意味する特殊変数です。&lt;br /&gt; 一時的に &lt;code&gt;$&amp;quot;&lt;/code&gt; の値を書き換えて、要素間に自動挿入する文字列をデフォルトの空白から任意の文字列に変更することもできます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;do { 
    17371737  local $&amp;quot; = &amp;quot; x &amp;quot;; 
    17381738  my @a = (&amp;apos;sin&amp;apos;, &amp;apos;cos&amp;apos;, &amp;apos;tan&amp;apos;); 
    17391739  print &amp;quot;@a\n&amp;quot;; 
    17401740}; 
    1741 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;sin x cos x tan&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;ここで、&lt;code&gt;&amp;quot;@a\n&amp;quot;&lt;/code&gt; の部分を &lt;code&gt;&amp;quot;@{[ リスト ]}\n&amp;quot;&lt;/code&gt; に置き換えて、&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print &amp;quot;@{[ &amp;apos;sin&amp;apos;, &amp;apos;cos&amp;apos;, &amp;apos;tan&amp;apos; ]}\n&amp;quot;; 
    1742 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;と、無名配列のデリファレンス &lt;code&gt;@{[ ]}&lt;/code&gt; を使うことによって、配列 &lt;code&gt;@a&lt;/code&gt; を使わずに、文字列中に直接リストの値を埋め込むことが可能になります。&lt;/p&gt;&lt;p&gt;このようにヒアドキュメントの他にも、ダブルクォーテーションで囲まれた文字列の中でも &lt;code&gt;@{[ リスト ]}&lt;/code&gt; のイディオムを使ってPerlの式を展開することができます。&lt;/p&gt;&lt;h2&gt;閑話休題&lt;/h2&gt;&lt;p&gt;&lt;a href="http://perl-users.jp/articles/advent-calendar/2008/12.html"&gt;数日前の復習&lt;/a&gt;ですが、Perlは破壊的な正規表現の置換を行なうので、以下のように複数行にわけて書くのが面倒という話がありました。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my $a = &amp;quot;AAA&amp;quot;; 
     1741&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;sin x cos x tan&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;ここで、&lt;code&gt;&amp;quot;@a\n&amp;quot;&lt;/code&gt; の部分を &lt;code&gt;&amp;quot;@{[ リスト ]}\n&amp;quot;&lt;/code&gt; に置き換えて、&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print &amp;quot;@{[ &amp;apos;sin&amp;apos;, &amp;apos;cos&amp;apos;, &amp;apos;tan&amp;apos; ]}\n&amp;quot;; 
     1742&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;と、無名配列のデリファレンス &lt;code&gt;@{[ ]}&lt;/code&gt; を使うことによって、配列 &lt;code&gt;@a&lt;/code&gt; を使わずに、文字列中に直接リストの値を埋め込むことが可能になります。&lt;/p&gt;&lt;p&gt;このようにヒアドキュメントの他にも、ダブルクォーテーションで囲まれた文字列の中でも &lt;code&gt;@{[ リスト ]}&lt;/code&gt; のイディオムを使ってPerlの式を展開することができます。&lt;/p&gt;&lt;h2&gt;閑話休題&lt;/h2&gt;&lt;p&gt;&lt;a href="http://perl-users.jp/articles/advent-calendar/2008/12.html"&gt;数日前の復習&lt;/a&gt;ですが、Perlは破壊的な正規表現の置換を行なうので、以下のように複数行にわけて書くのが面倒という話がありました。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my $a = &amp;quot;AAA&amp;quot;; 
    17431743my $b = $a; 
    17441744   $b =~ s/A/B/g; 
    17451745print &amp;quot;&amp;apos;$a&amp;apos; =&amp;gt; &amp;apos;$b&amp;apos;,\n&amp;quot;; 
    1746 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;&amp;apos;AAA&amp;apos; =&amp;gt; &amp;apos;BBB&amp;apos;, 
    1747 &lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;これは、&lt;code&gt;$b = $a&lt;/code&gt; の代入文を &lt;code&gt;( )&lt;/code&gt; で括って、置換演算子 &lt;code&gt;=~&lt;/code&gt; の左辺に持ってくることによって1行短縮することができます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my $a = &amp;quot;AAA&amp;quot;; 
     1746&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;&amp;apos;AAA&amp;apos; =&amp;gt; &amp;apos;BBB&amp;apos;, 
     1747&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;これは、&lt;code&gt;$b = $a&lt;/code&gt; の代入文を &lt;code&gt;( )&lt;/code&gt; で括って、置換演算子 &lt;code&gt;=~&lt;/code&gt; の左辺に持ってくることによって1行短縮することができます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my $a = &amp;quot;AAA&amp;quot;; 
    17481748( my $b = $a ) =~ s/A/B/g; 
    1749 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;代入演算子 &lt;code&gt;=&lt;/code&gt; は左結合なので、さらに変数 &lt;code&gt;$a&lt;/code&gt; の初期化も1行にまとめることができます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;( my $b = my $a = &amp;quot;AAA&amp;quot; ) =~ s/A/B/g; 
    1750 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これは、&lt;code&gt;my&lt;/code&gt;の存在しなかったPerl4の時代で基本的なテクニックだったそうです。&lt;/p&gt;&lt;h2&gt;@{[ リスト ]} の応用例&lt;/h2&gt;&lt;p&gt;ここで&lt;code&gt;map&lt;/code&gt;を使えば一時変数の名前もつけなくてよくなるはず…と思って以下のコードを書いて実行してみます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my ($b) = map { s/A/B/g; $_ } (&amp;quot;AAA&amp;quot;); 
    1751 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;Modification of a read-only value attempted at - line 1.&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;しかし、このコードは Perl に怒られてエラーになってしまいます。&lt;/p&gt;&lt;p&gt;&lt;code&gt;(&amp;quot;AAA&amp;quot;)&lt;/code&gt; としただけでは &lt;code&gt;&amp;quot;AAA&amp;quot;&lt;/code&gt; は文字列定数(read-only value)と解釈されるので、値の変更ができないのです。&lt;/p&gt;&lt;h3&gt;map の初期値に @{[]}&lt;/h3&gt;&lt;p&gt;そこで登場するのが &lt;code&gt;@{[ リスト ]}&lt;/code&gt; の応用例です。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my ($b) = map { s/A/B/g; $_ } @{[&amp;quot;AAA&amp;quot;]}; 
    1752 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;[&amp;quot;AAA&amp;quot;]&lt;/code&gt;で無名配列を作ってすぐに&lt;code&gt;@{}&lt;/code&gt;でデリファレンスしてあげれば、 一時的な配列を作成することができます。&lt;br /&gt;この配列の値は破壊的な変更が可能です。&lt;/p&gt;&lt;h3&gt;grep の第一引数に s///&lt;/h3&gt;&lt;p&gt;ちなみに、&lt;code&gt;map&lt;/code&gt; の他に &lt;code&gt;grep&lt;/code&gt; を使っても同じようなコードを書くことができます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;my ($b) = grep s/A/B/g || 1, @{[&amp;quot;AAA&amp;quot;]}; 
    1753 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このとき &lt;code&gt;|| 1&lt;/code&gt; の部分を省略してしまうと、 &lt;code&gt;s///&lt;/code&gt; の戻り値がそのまま評価されてしまうので、置換に失敗した要素が取り除かれてしまいます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print join &amp;quot;:&amp;quot;, grep s/A/B/g, @{[&amp;quot;AAA&amp;quot;, &amp;quot;ABC&amp;quot;, &amp;quot;XXX&amp;quot;, &amp;quot;A&amp;quot;]}; 
    1754 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;BBB:BBC:B&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;s/A/B/&lt;/code&gt; の置換に失敗した &lt;code&gt;&amp;quot;XXX&amp;quot;&lt;/code&gt; の値も含めたい場合は、&lt;code&gt;s&lt;/code&gt; の後ろに &lt;code&gt;|| 1&lt;/code&gt; をつけて、パターンマッチの結果に関わらず常に真になるようにします。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;print join &amp;quot;:&amp;quot;, grep s/A/B/g || 1, @{[&amp;quot;AAA&amp;quot;, &amp;quot;ABC&amp;quot;, &amp;quot;XXX&amp;quot;, &amp;quot;A&amp;quot;]}; 
    1755 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre&gt;&lt;samp&gt;BBB:BBC:XXX:B&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;次は国内滞在説が根強い id:miyagawa さんにお願いしたいと思います。;-)&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
     1749&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;代入演算子 &lt;code&gt;=&lt;/code&gt; は左結合なので、さらに変数 &lt;code&gt;$a&lt;/code&gt; の初期化も1行にまとめることができます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;( my $b = my $a = &amp;quot;AAA&amp;quot; ) =~ s/A/B/g; 
     1750&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これは、&lt;code&gt;my&lt;/code&gt;の存在しなかったPerl4の時代で基本的なテクニックだったそうです。&lt;/p&gt;&lt;h2&gt;@{[ リスト ]} の応用例&lt;/h2&gt;&lt;p&gt;ここで&lt;code&gt;map&lt;/code&gt;を使えば一時変数の名前もつけなくてよくなるはず…と思って以下のコードを書いて実行してみます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my ($b) = map { s/A/B/g; $_ } (&amp;quot;AAA&amp;quot;); 
     1751&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;Modification of a read-only value attempted at - line 1.&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;しかし、このコードは Perl に怒られてエラーになってしまいます。&lt;/p&gt;&lt;p&gt;&lt;code&gt;(&amp;quot;AAA&amp;quot;)&lt;/code&gt; としただけでは &lt;code&gt;&amp;quot;AAA&amp;quot;&lt;/code&gt; は文字列定数(read-only value)と解釈されるので、値の変更ができないのです。&lt;/p&gt;&lt;h3&gt;map の初期値に @{[]}&lt;/h3&gt;&lt;p&gt;そこで登場するのが &lt;code&gt;@{[ リスト ]}&lt;/code&gt; の応用例です。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my ($b) = map { s/A/B/g; $_ } @{[&amp;quot;AAA&amp;quot;]}; 
     1752&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;[&amp;quot;AAA&amp;quot;]&lt;/code&gt;で無名配列を作ってすぐに&lt;code&gt;@{}&lt;/code&gt;でデリファレンスしてあげれば、 一時的な配列を作成することができます。&lt;br /&gt;この配列の値は破壊的な変更が可能です。&lt;/p&gt;&lt;h3&gt;grep の第一引数に s///&lt;/h3&gt;&lt;p&gt;ちなみに、&lt;code&gt;map&lt;/code&gt; の他に &lt;code&gt;grep&lt;/code&gt; を使っても同じようなコードを書くことができます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my ($b) = grep s/A/B/g || 1, @{[&amp;quot;AAA&amp;quot;]}; 
     1753&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このとき &lt;code&gt;|| 1&lt;/code&gt; の部分を省略してしまうと、 &lt;code&gt;s///&lt;/code&gt; の戻り値がそのまま評価されてしまうので、置換に失敗した要素が取り除かれてしまいます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print join &amp;quot;:&amp;quot;, grep s/A/B/g, @{[&amp;quot;AAA&amp;quot;, &amp;quot;ABC&amp;quot;, &amp;quot;XXX&amp;quot;, &amp;quot;A&amp;quot;]}; 
     1754&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;BBB:BBC:B&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;s/A/B/&lt;/code&gt; の置換に失敗した &lt;code&gt;&amp;quot;XXX&amp;quot;&lt;/code&gt; の値も含めたい場合は、&lt;code&gt;s&lt;/code&gt; の後ろに &lt;code&gt;|| 1&lt;/code&gt; をつけて、パターンマッチの結果に関わらず常に真になるようにします。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;print join &amp;quot;:&amp;quot;, grep s/A/B/g || 1, @{[&amp;quot;AAA&amp;quot;, &amp;quot;ABC&amp;quot;, &amp;quot;XXX&amp;quot;, &amp;quot;A&amp;quot;]}; 
     1755&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行結果:&lt;/p&gt;&lt;pre class="lang-html"&gt;&lt;samp&gt;BBB:BBC:XXX:B&lt;/samp&gt;&lt;/pre&gt;&lt;p&gt;次は国内滞在説が根強い id:miyagawa さんにお願いしたいと思います。;-)&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
    17561756</content:encoded> 
    1757       <dcterms:modified>2008-12-15T02:23:17Z</dcterms:modified> 
     1757      <dcterms:modified>2008-12-16T13:43:19Z</dcterms:modified> 
    17581758      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/14.html</guid> 
    17591759    </item> 
     
    17621762      <dc:creator>nobody@example.com</dc:creator> 
    17631763      <link>http://perl-users.jp/articles/advent-calendar/2008/15.html</link> 
    1764       <description>perldoc を使いこなす国内滞在説が根強い miyagawa です。アメリカ合衆国国内という意味であれば、いつもそうなんですが。今回は意外と知られていないと思われる perldoc コマンドの使い方を紹介します。perldoc は Perl モジュールに含まれる POD ドキュメントを整形して man 表示するツールで、perldoc モジュール名のようにして実行します。% perldoc Web::Scraper-l オプションをつけるとそのモジュールのあるパス、-m オプションで POD の代わりにソースコードそのものを表示することができます。% perldoc -l Web::Scraper 
     1764      <description>perldoc を使いこなす国内滞在説が根強い miyagawa です。アメリカ合衆国国内という意味であれば、いつもそうなんですが。今回は意外と知られていないと思われる perldoc コマンドの使い方を紹介します。perldoc は Perl モジュールに含まれる POD ドキュメントを整形して man 表示するツールで、perldoc モジュール名のようにして実行します。% perldoc Web::Scraper 
     1765-l オプションをつけるとそのモジュールのあるパス、-m オプションで POD の代わりにソースコードそのものを表示することができます。% perldoc -l Web::Scraper 
    17651766/Library/Perl/5.8.6/Web/Scraper.pm 
    17661767# .pm ファイルを vi で開く 
    17671768% vi `perldoc -l Web::Scraper` 
    17681769# .pm ファイルを PAGER で開く 
    1769 % perldoc -m Web::Scraper  
    1770 エラーにファイル名と行数が書いてあってその部分を見たい、なんてときには emacsやviなどにパイプで渡して開くと便利ですね。-f オプションは perl の組み込み関数のドキュメントを表示します。% perldoc -f index 
     1770% perldoc -m Web::Scraper 
     1771エラーにファイル名と行数が書いてあってその部分を見たい、なんてときには Emacs や Vim などにパイプで渡して開くと便利ですね。-f オプションは Perl の組み込み関数のドキュメントを表示します。% perldoc -f index 
    17711772       index STR,SUBSTR,POSITION 
    17721773       index STR,SUBSTR 
     
    17831784次は sekimura さん。 
    17841785</description> 
    1785       <dc:date>2008-12-15T23:45:43Z</dc:date> 
     1786      <dc:date>2008-12-16T11:03:38Z</dc:date> 
    17861787      <title>perldoc を使いこなす</title> 
    1787       <pubDate>Mon, 15 Dec 2008 23:45:43 -0000</pubDate> 
    1788       <content:encoded>&lt;body&gt;&lt;h1&gt;perldoc を使いこなす&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;国内滞在説が根強い miyagawa です。アメリカ合衆国国内という意味であれば、いつもそうなんですが。&lt;/p&gt;&lt;p&gt;今回は意外と知られていないと思われる perldoc コマンドの使い方を紹介します。perldoc は Perl モジュールに含まれる POD ドキュメントを整形して man 表示するツールで、perldoc モジュール名のようにして実行します。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc Web::Scraper&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;-l オプションをつけるとそのモジュールのあるパス、-m オプションで POD の代わりにソースコードそのものを表示することができます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc -l Web::Scraper 
     1788      <pubDate>Tue, 16 Dec 2008 11:03:38 -0000</pubDate> 
     1789      <content:encoded>&lt;body&gt;&lt;h1&gt;perldoc を使いこなす&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;国内滞在説が根強い miyagawa です。アメリカ合衆国国内という意味であれば、いつもそうなんですが。&lt;/p&gt;&lt;p&gt;今回は意外と知られていないと思われる perldoc コマンドの使い方を紹介します。perldoc は Perl モジュールに含まれる POD ドキュメントを整形して man 表示するツールで、perldoc モジュール名のようにして実行します。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc Web::Scraper 
     1790&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;-l&lt;/code&gt; オプションをつけるとそのモジュールのあるパス、&lt;code&gt;-m&lt;/code&gt; オプションで POD の代わりにソースコードそのものを表示することができます。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc -l Web::Scraper 
    17891791/Library/Perl/5.8.6/Web/Scraper.pm 
    17901792# .pm ファイルを vi で開く 
    17911793% vi `perldoc -l Web::Scraper` 
    17921794# .pm ファイルを PAGER で開く 
    1793 % perldoc -m Web::Scraper  
    1794 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;エラーにファイル名と行数が書いてあってその部分を見たい、なんてときには emacsやviなどにパイプで渡して開くと便利ですね。&lt;/p&gt;&lt;p&gt;-f オプションは perl の組み込み関数のドキュメントを表示します。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc -f index 
     1795% perldoc -m Web::Scraper 
     1796&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;エラーにファイル名と行数が書いてあってその部分を見たい、なんてときには Emacs や Vim などにパイプで渡して開くと便利ですね。&lt;/p&gt;&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; オプションは Perl の組み込み関数のドキュメントを表示します。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% perldoc -f index 
    17951797       index STR,SUBSTR,POSITION 
    17961798       index STR,SUBSTR 
     
    18031805               to--but don&amp;apos;t do that).  If the substring is not found, returns 
    18041806               one less than the base, ordinarily &amp;quot;-1&amp;quot;. 
    1805 &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;よく &lt;a href="http://perl-users.jp/articles/advent-calendar/2008/06.html"&gt;-X ファイルテスト演算子&lt;/a&gt; の対応を忘れてしまって困りますが、そういうときは perldoc -f -X とすると一覧がでてきます。&lt;/p&gt;&lt;p&gt;そうそう、ターミナルのロケールに UTF-8 を設定している場合、&lt;a href="http://use.perl.org/~jbisbee/journal/36868"&gt;perldoc と nroff では、コードに含まれるシングルクォートやダブルクォートが UTF-8 の全角文字に変換されてしまい、ペーストしても動かない&lt;/a&gt; という問題があります。ちょっとバッドノウハウ気味ですが、perldoc に -t オプションをつけていつもテキスト表示するか、一時的に LANG 環境変数を無効化することで対応しています。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% alias perldoc 
     1807&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;よく &lt;a href="http://perl-users.jp/articles/advent-calendar/2008/06.html"&gt;&lt;code&gt;-X&lt;/code&gt; ファイルテスト演算子&lt;/a&gt; の対応を忘れてしまって困りますが、そういうときは &lt;code&gt;perldoc -f -X&lt;/code&gt; とすると一覧がでてきます。&lt;/p&gt;&lt;p&gt;そうそう、ターミナルのロケールに UTF-8 を設定している場合、&lt;a href="http://use.perl.org/~jbisbee/journal/36868"&gt;perldoc と nroff では、コードに含まれるシングルクォートやダブルクォートが UTF-8 の全角文字に変換されてしまい、ペーストしても動かない&lt;/a&gt; という問題があります。ちょっとバッドノウハウ気味ですが、perldoc に &lt;code&gt;-t&lt;/code&gt; オプションをつけていつもテキスト表示するか、一時的に &lt;var&gt;LANG&lt;/var&gt; 環境変数を無効化することで対応しています。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;% alias perldoc 
    18061808env LANG=C perldoc 
    18071809&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次は sekimura さん。&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
    18081810</content:encoded> 
    1809       <dcterms:modified>2008-12-15T23:45:43Z</dcterms:modified> 
     1811      <dcterms:modified>2008-12-16T11:03:38Z</dcterms:modified> 
    18101812      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/15.html</guid> 
     1813    </item> 
     1814    <item> 
     1815      <author>nobody@example.com</author> 
     1816      <dc:creator>nobody@example.com</dc:creator> 
     1817      <link>http://perl-users.jp/articles/advent-calendar/2008/16.html</link> 
     1818      <description>Perl の map と grep を使うすしを奢らなければいけないなんて、バトンを渡されてから知りました。おいしい寿司が食いたい sekimura です。今回は使いこなすと気持ちよくて、使いすぎると気持ち悪いと言われてしまう grep と map の使い方について紹介します。この二つは文法がよく似ていて、同時に使われることも多いので一気に両方の使い方を覚えるのをおすすめします。grep: 配列をフィルターするまずは、前回覚えた perldoc を使って grep とはなにかを調べてみましょう。$ perldoc -f grep 
     1819       grep BLOCK LIST 
     1820       grep EXPR,LIST 
     1821               This is similar in spirit to, but not the same as, grep(1) and 
     1822               its relatives.  In particular, it is not limited to using 
     1823               regular expressions. 
     1824 
     1825               Evaluates the BLOCK or EXPR for each element of LIST (locally 
     1826               setting $_ to each element) and returns the list value 
     1827               consisting of those elements for which the expression evaluated 
     1828               to true.  In scalar context, returns the number of times the 
     1829               expression was true. 
     1830「UNIX コマンドの grep 等のコマンドと似てるけど違うもの。だって正規表現以外も使えるんだぜ」とか書いていますね。LIST の全要素を($_ を局所的にセットしながら)BLOCK か EXPR で評価し、その結果が真となるものだけからなる配列を返します。スカラコンテキストの場合は、結果が真となる要素の数を返します。例えば %ENV のキーからなる配列から "H" で始まるものだけを抜き出すには以下のようにします。$ perl -e 'print join " ", (grep /^H/, keys %ENV), "\n"' 
     1831HOME HISTCONTROL 
     1832grep は BLOCK を使った場合にもっと楽しくなります。例えば、以下のように、ある二つの配列をつなぎ合わせたものから、重複を取り除いた配列を得ることができます。my @cities = ('Sapporo', 'Nishitokyo', 'Yokohama'); 
     1833my @prefs  = ('Hokkaido', 'Tokyo', 'Yokohama'); 
     1834my %seen; 
     1835 
     1836my @uniq = grep { ++$seen{$_} &lt; 2 } (@cities, @prefs); 
     1837 
     1838## @uniq には ('Sapporo', 'Nishitokyo', 'Yokohama', 'Hokkaido', 'Tokyo') が入る。 
     1839逆に重複したものだけ抜き出したいときには以下のように grep で取得した配列に対して grep することで得られます。my @lunch  = ('Bento', 'Ramen', 'Onigiri', 'Curry'); 
     1840my @dinner = ('Tonkatsu', 'Ramen', 'Curry'); 
     1841my %seen; 
     1842 
     1843my @dup = grep { $seen{$_} &gt;= 2 } grep { ++$seen{$_} &gt; 1 } (@luch, @dinner); 
     1844 
     1845## @dup には ('Ramen', 'Curry') が入る。 
     1846map: 配列の要素を変換する例によって perldoc -f map しましょう。$ perldoc -f map 
     1847       map BLOCK LIST 
     1848       map EXPR,LIST 
     1849              Evaluates the BLOCK or EXPR for each element of LIST (locally 
     1850              setting $_ to each element) and returns the list value composed 
     1851              of the results of each such evaluation.  In scalar context, 
     1852              returns the total number of elements so generated.  Evaluates 
     1853              BLOCK or EXPR in list context, so each element of LIST may 
     1854              produce zero, one, or more elements in the returned value. 
     1855ほとんど同じことが書いてありますね。grep はフィルターなので、得られる配列は与えられた配列のサブセットになるのに対して、map では与えられた各要素を変換し、その結果を配列として得ることが可能です。my %price_map = ( 
     1856  'Ramen' =&gt; 400, 
     1857  'Curry' =&gt; 650, 
     1858  'Katsudon' =&gt; 600, 
     1859); 
     1860my @today = ('Ramen', 'Curry'); 
     1861my @meshi_dai = map { $price_map{$_} } @today; 
     1862## @meshi_dai には ('400', '650') が入る。 
     1863 
     1864my @zei_komi = map { $_ x 1.05 } @meshi_dai; 
     1865## @zei_komi には ('420', '682.5') が入る。 
     1866grep のときにはスルーしましたが、 BLOCK 内での $_ は元の要素のリファレンスなので、$_ を変更してしまうと、元の要素も変更されてしまいます。よく、「破壊的」と呼ばれるケースですね。これを防ぐには、 BLOCK の内部で my 変数にコピーしてから変更を加えていきます。my @addresses = ('katsuo@example.com', 'wakame@example.com', 'tara@example.com'); 
     1867my @no_spam = map { my $email = $_; $email =~ s/\@/ at /; $email } @addresses; 
     1868 
     1869## @no_spam には ('katsuo at example.com', 'wakame at example.com', 'tara at example.com) が入る。 
     1870このようにして、@addresses の要素を変更すること無く @no_spam という変換後の要素を持つ配列を得ることができます。使いどころgrep, map 両方共 for, foreach のループで書き換えることができますが、それぞれ「フィルター」と「変換」という意味をコードを読む人に的確に伝えることができるのがメリットではないでしょうか。その他にも、デバッガーやワンライナーでループ処理を簡素に書けるのも利点です。 sort 等のコマンドと組み合わせて UNIX のパイプのようにデータを処理すると自分が偉くなったような錯覚に陥るのがオススメどころです。 ただし、 grep, map を単にループ処理をするために、左辺値を受け取らずに使うのはコードを読む人を混乱させるので避けた方がいいでしょう。 (SEE ALSO perldoc perlstyle) 次は nipotan さん と思ったら風邪引いてピンチだそうで。 antipop さんお願いします。 
     1871</description> 
     1872      <dc:date>2008-12-17T13:37:36Z</dc:date> 
     1873      <title>Perl の map と grep を使う</title> 
     1874      <pubDate>Wed, 17 Dec 2008 13:37:36 -0000</pubDate> 
     1875      <content:encoded>&lt;body&gt;&lt;h1&gt;Perl の map と grep を使う&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;すしを奢らなければいけないなんて、バトンを渡されてから知りました。おいしい寿司が食いたい sekimura です。&lt;/p&gt;&lt;p&gt;今回は使いこなすと気持ちよくて、使いすぎると気持ち悪いと言われてしまう &lt;code&gt;grep&lt;/code&gt; と &lt;code&gt;map&lt;/code&gt; の使い方について紹介します。この二つは文法がよく似ていて、同時に使われることも多いので一気に両方の使い方を覚えるのをおすすめします。&lt;/p&gt;&lt;h2&gt;grep: 配列をフィルターする&lt;/h2&gt;&lt;p&gt;まずは、前回覚えた perldoc を使って &lt;code&gt;grep&lt;/code&gt; とはなにかを調べてみましょう。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perldoc -f grep 
     1876       grep BLOCK LIST 
     1877       grep EXPR,LIST 
     1878               This is similar in spirit to, but not the same as, grep(1) and 
     1879               its relatives.  In particular, it is not limited to using 
     1880               regular expressions. 
     1881 
     1882               Evaluates the BLOCK or EXPR for each element of LIST (locally 
     1883               setting $_ to each element) and returns the list value 
     1884               consisting of those elements for which the expression evaluated 
     1885               to true.  In scalar context, returns the number of times the 
     1886               expression was true. 
     1887&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;「UNIX コマンドの &lt;code&gt;grep&lt;/code&gt; 等のコマンドと似てるけど違うもの。だって正規表現以外も使えるんだぜ」とか書いていますね。LIST の全要素を(&lt;code&gt;$_&lt;/code&gt; を局所的にセットしながら)BLOCK か EXPR で評価し、その結果が真となるものだけからなる配列を返します。スカラコンテキストの場合は、結果が真となる要素の数を返します。例えば &lt;code&gt;%ENV&lt;/code&gt; のキーからなる配列から &lt;code&gt;&amp;quot;H&amp;quot;&lt;/code&gt; で始まるものだけを抜き出すには以下のようにします。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perl -e &amp;apos;print join &amp;quot; &amp;quot;, (grep /^H/, keys %ENV), &amp;quot;\n&amp;quot;&amp;apos; 
     1888HOME HISTCONTROL 
     1889&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; は BLOCK を使った場合にもっと楽しくなります。例えば、以下のように、ある二つの配列をつなぎ合わせたものから、重複を取り除いた配列を得ることができます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my @cities = (&amp;apos;Sapporo&amp;apos;, &amp;apos;Nishitokyo&amp;apos;, &amp;apos;Yokohama&amp;apos;); 
     1890my @prefs  = (&amp;apos;Hokkaido&amp;apos;, &amp;apos;Tokyo&amp;apos;, &amp;apos;Yokohama&amp;apos;); 
     1891my %seen; 
     1892 
     1893my @uniq = grep { ++$seen{$_} &amp;lt; 2 } (@cities, @prefs); 
     1894 
     1895## @uniq には (&amp;apos;Sapporo&amp;apos;, &amp;apos;Nishitokyo&amp;apos;, &amp;apos;Yokohama&amp;apos;, &amp;apos;Hokkaido&amp;apos;, &amp;apos;Tokyo&amp;apos;) が入る。 
     1896&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;逆に重複したものだけ抜き出したいときには以下のように &lt;code&gt;grep&lt;/code&gt; で取得した配列に対して &lt;code&gt;grep&lt;/code&gt; することで得られます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my @lunch  = (&amp;apos;Bento&amp;apos;, &amp;apos;Ramen&amp;apos;, &amp;apos;Onigiri&amp;apos;, &amp;apos;Curry&amp;apos;); 
     1897my @dinner = (&amp;apos;Tonkatsu&amp;apos;, &amp;apos;Ramen&amp;apos;, &amp;apos;Curry&amp;apos;); 
     1898my %seen; 
     1899 
     1900my @dup = grep { $seen{$_} &amp;gt;= 2 } grep { ++$seen{$_} &amp;gt; 1 } (@luch, @dinner); 
     1901 
     1902## @dup には (&amp;apos;Ramen&amp;apos;, &amp;apos;Curry&amp;apos;) が入る。 
     1903&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;map: 配列の要素を変換する&lt;/h2&gt;&lt;p&gt;例によって &lt;code&gt;perldoc -f map&lt;/code&gt; しましょう。&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ perldoc -f map 
     1904       map BLOCK LIST 
     1905       map EXPR,LIST 
     1906              Evaluates the BLOCK or EXPR for each element of LIST (locally 
     1907              setting $_ to each element) and returns the list value composed 
     1908              of the results of each such evaluation.  In scalar context, 
     1909              returns the total number of elements so generated.  Evaluates 
     1910              BLOCK or EXPR in list context, so each element of LIST may 
     1911              produce zero, one, or more elements in the returned value. 
     1912&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ほとんど同じことが書いてありますね。&lt;code&gt;grep&lt;/code&gt; はフィルターなので、得られる配列は与えられた配列のサブセットになるのに対して、&lt;code&gt;map&lt;/code&gt; では与えられた各要素を変換し、その結果を配列として得ることが可能です。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my %price_map = ( 
     1913  &amp;apos;Ramen&amp;apos; =&amp;gt; 400, 
     1914  &amp;apos;Curry&amp;apos; =&amp;gt; 650, 
     1915  &amp;apos;Katsudon&amp;apos; =&amp;gt; 600, 
     1916); 
     1917my @today = (&amp;apos;Ramen&amp;apos;, &amp;apos;Curry&amp;apos;); 
     1918my @meshi_dai = map { $price_map{$_} } @today; 
     1919## @meshi_dai には (&amp;apos;400&amp;apos;, &amp;apos;650&amp;apos;) が入る。 
     1920 
     1921my @zei_komi = map { $_ x 1.05 } @meshi_dai; 
     1922## @zei_komi には (&amp;apos;420&amp;apos;, &amp;apos;682.5&amp;apos;) が入る。 
     1923&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; のときにはスルーしましたが、 BLOCK 内での &lt;code&gt;$_&lt;/code&gt; は元の要素のリファレンスなので、&lt;code&gt;$_&lt;/code&gt; を変更してしまうと、元の要素も変更されてしまいます。よく、「破壊的」と呼ばれるケースですね。これを防ぐには、 BLOCK の内部で &lt;code&gt;my&lt;/code&gt; 変数にコピーしてから変更を加えていきます。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my @addresses = (&amp;apos;katsuo@example.com&amp;apos;, &amp;apos;wakame@example.com&amp;apos;, &amp;apos;tara@example.com&amp;apos;); 
     1924my @no_spam = map { my $email = $_; $email =~ s/\@/ at /; $email } @addresses; 
     1925 
     1926## @no_spam には (&amp;apos;katsuo at example.com&amp;apos;, &amp;apos;wakame at example.com&amp;apos;, &amp;apos;tara at example.com) が入る。 
     1927&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このようにして、&lt;code&gt;@addresses&lt;/code&gt; の要素を変更すること無く &lt;code&gt;@no_spam&lt;/code&gt; という変換後の要素を持つ配列を得ることができます。&lt;/p&gt;&lt;h2&gt;使いどころ&lt;/h2&gt;&lt;p&gt;&lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; 両方共 &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;foreach&lt;/code&gt; のループで書き換えることができますが、それぞれ「フィルター」と「変換」という意味をコードを読む人に的確に伝えることができるのがメリットではないでしょうか。その他にも、デバッガーやワンライナーでループ処理を簡素に書けるのも利点です。 &lt;code&gt;sort&lt;/code&gt; 等のコマンドと組み合わせて UNIX のパイプのようにデータを処理すると自分が偉くなったような錯覚に陥るのがオススメどころです。 &lt;/p&gt;&lt;p&gt;ただし、 &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; を単にループ処理をするために、左辺値を受け取らずに使うのはコードを読む人を混乱させるので避けた方がいいでしょう。 (SEE ALSO &lt;code&gt;perldoc perlstyle&lt;/code&gt;) &lt;/p&gt;&lt;p&gt;次は &lt;del&gt;nipotan さん&lt;/del&gt; と思ったら風邪引いてピンチだそうで。 antipop さんお願いします。&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
     1928</content:encoded> 
     1929      <dcterms:modified>2008-12-17T13:37:36Z</dcterms:modified> 
     1930      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/16.html</guid> 
     1931    </item> 
     1932    <item> 
     1933      <author>nobody@example.com</author> 
     1934      <dc:creator>nobody@example.com</dc:creator> 
     1935      <link>http://perl-users.jp/articles/advent-calendar/2008/17.html</link> 
     1936      <description>酔っぱらった勢いでコードを書く際に大切なことプライベートでコードを書く時は、たいていビールを飲みながらってな毎日のkentaro a.k.a. id:antipopです。こんにちは。そんなわけで、ただでさえtypoが多いのに加えて、酔いにより手元はボロボロ。調子良く書いていても、つまらないtypoをいちいち修正してまわっていると、せっかくの気分のいい酔いも覚めてしまうというものです。そこで、コードを書く時には酒を飲まない、という以外の対策を考えてみました。とにかく全部ぶっつぶすひとはどうしたところで間違いを犯すものです。酔っぱらっていても酔っぱらってなくても、それは同じ。ならば、あり得る名前をあらかじめ定義してはどうか、と考えました。たとえば以下のようなクラスを定義したとします。package Hoge::Fuga::Piyo; 
     1937use strict; 
     1938use warnings; 
     1939 
     1940# ... (snip) ... 
     1941 
     19421; 
     1943このクラスを使う際に、上記したように手元不如意の状態に陥っていると、ついつい以下のように書いたりして、怒られたりします。my $obj = Hgeo::Ufag::Poyi-&gt;new; 
     1944こんなことではいつtypoをしてしまうか心配で、あっという間に酔いも覚めてしまうでしょう。この大変に深刻な問題避けるにはどうしたらいいか。そうです。Hoge::Fuga::Piyoという正しいパッケージ名から得られる、あり得る組合せのクラスをあらかじめ定義してまわれば、たとえ上記のようなコードを書いてしまったとしても、つつがなく、期待通りにスクリプトは動作し、酔い心地を邪魔されることもありません。というわけで、なんらかの方法でもってHoge::Fuga::Piyoの順列組合せを生成して、その名前を元にパッケージを定義してみようと思い立ちました。さて、どのぐらいの組合せがあるのでしょうか。ここでは、パッケージ名に含まれるアルファベットの大文字小文字を考慮しない。組合せは::で分割された文字列どうしで行われる、という条件を置く。::で分割された各パートに含まれる文字を全て使う。つまり各パートの文字数は変わらない。すると、組合せの数はHoge::Fuga::Piyoの場合、4! * 4! * 4! = 1,000通りになります。もしパッケージ名がSome::Complicated::Nameのようなものだった場合、4! * 11! * 4! = 6,600通りなんてな大きな数字になってしまいます。これではダメです……。もう少し賢くさすがに、あり得るものを全部網羅しようなんて無茶でした。それに上記の条件だと組み合わせに過ぎないので、typoにありがちな隣のキーを押してしまったというような状況を救うことができません。もっと人間の現実にやりがちな間違いに適切に対応した、賢い仕組みが必要です。そこでCPANを漁ってみると、Acme::Tpyoなんてな、その名前からしてひとを食ったようなモジュールが見つかります。ちなみにTpyoは僕がtypoしたのではなく、モジュール名自体がtypoを表現しています。これはどんなモジュールかというと、ある文字列を渡すと、わざとtypoした文章を生成して返してくれるというものです。しかも、ただ単にtypoした文字列を返すだけではなく、typingしているひとの性格や能力、その時の状態をエミュレートしてtypoしてくれるというインテリジェントなtypoマシーンなのです。たとえば、typistがキーをどれだけミスタイプしがちか、指の太さ、キータッチの強さ、カフェインや、はたまたアルコールの摂取状況なんてことまで考慮してくれます。まさに、今回の問題を解決するに際して、まさにぴったりの機能を提供してくれるものであるといえます。typo safeな環境を作るそこで、上述のAcme::Tpyoを用いて、typoに強い環境を作ってみましょう。その際、基本的には「全方位作戦」の方針を踏襲しますが、無制限に候補を羅列してもしかたがないし、また、Acme::Tpyoのインテリジェントなtypo生成能力により現実的にあり得る間違いをかなりしぼれると思わるので、適当な数だけ候補を生成するようにして、大体において役立ちそうというラインで満足するようにしておきましょう。ここではAcme::Class::TypoSafeというモジュールを作成してみました。実装の詳細を検討する前に、まずは使い方を見ておきましょう。このモジュールのテストコードを以下に示します。use strict; 
     1945use warnings; 
     1946use Test::More qw(no_plan); 
     1947use UNIVERSAL::require; 
     1948 
     1949package Some::Complicated::Name; 
     1950use Acme::Class::TypoSafe; 
     1951 
     1952sub new { bless {}, shift } 
     1953sub difficult_to_type_correctly {} 
     1954 
     1955package main; 
     1956 
     1957my %packages = Acme::Class::TypoSafe-&gt;typo_packages; 
     1958for my $package (keys %packages) { 
     1959    my $obj = $package-&gt;new; 
     1960    isa_ok $obj, $package; 
     1961    isa_ok $obj, 'Some::Complicated::Name'; 
     1962    can_ok $obj, ('new', 'difficult_to_type_correctly', @{$packages{$package}}); 
     1963} 
     1964ここでは、Some::Complicated::Nameというクラスを定義して、それを使ってコードを書いていこうとしています。Acme::Class::TypoSafeの使い方は上記の通り簡単で、単にuseするだけです。その結果、デフォルトでは100通りのtypoしたらこうなるだろうなというパッケージ名を生成して、それをAcme::Class::TypoSafeをuseしたモジュールの子クラスとして定義します。 package Some::Complicated::Name; 
     1965use Acme::Class::TypoSafe; 
     1966 
     1967# ... (snip) ... 
     1968 
     1969package main; 
     1970my $foo = Sone::Conplicared::Name-&gt;new; 
     1971my $bar = Sien::Cmopcalired::Nane-&gt;new; 
     1972酔っぱらって手元不如意のままこんなコードを書いても、もう安心です。ちょっとしたtypoぐらい気にかけなくても、各種パラメタの調整具合や、確率的な事情にもよりますが、けっこう拾ってくれるようです。さらにtypoしてみるここまでは、パッケージ名についてtypoした場合のことしか考慮していませんでした。typoにおいて更に深刻なのは、パッケージ名よりも書く機会の多いメソッド名でしょう。そこで、Acme::Class::TypoSafeを、メソッド名についてもuse元パッケージのメソッド一覧からそれぞれのtypo文字列を生成してエイリアスメソッドを定義するということにしました。……といいたいところなのですが、この記事を書いている時点では、以下のように実装してみたものの、use元のメソッド一覧を取得することができず、そのためメソッド名についてはいまも安心できない状況が続いています。package Acme::Class::TypoSafe; 
     1973use strict; 
     1974use warnings; 
     1975use Acme::Tpyo; 
     1976use Class::Inspector; 
     1977 
     1978our $VERSION       = '0.01'; 
     1979our %TYPO_PACKAGES = (); 
     1980 
     1981sub import { 
     1982    my ($class, %args) = @_; 
     1983    my $package = caller; 
     1984    my $keyset  = delete $args{keyset}; 
     1985    my $tpyist  = delete $args{tpyist}; 
     1986    my $count   = delete $args{count} || 100; 
     1987    my $tpyo    = Acme::Tpyo-&gt;new($keyset, $tpyist); 
     1988 
     1989    my $i = 0; 
     1990    while ($i &lt; $count)  { 
     1991        my $typo_package = join '::', map { 
     1992            my $part = $_; 
     1993            my $typo = $tpyo-&gt;misspell($part); 
     1994            ucfirst(lc($typo)); 
     1995        } split '::', $package; 
     1996 
     1997        next if $package eq $typo_package           || 
     1998                $typo_package =~ /[^[:alnum:]_\:]/; 
     1999 
     2000        # define typo packages 
     2001        eval &lt;&lt;"EOS"; 
     2002package $typo_package; 
     2003use base qw($package); 
     2004EOS 
     2005        $TYPO_PACKAGES{$typo_package} = []; 
     2006 
     2007        # define typo functions for typo packages 
     2008        for my $function (@{Class::Inspector-&gt;functions($package)}) { 
     2009            warn $function; 
     2010            for (1 .. $count) { 
     2011                my $typo_function = $tpyo-&gt;misspell($function); 
     2012                warn $typo_function; 
     2013                next if $function eq $typo_function        || 
     2014                        $typo_function =~ /[^[:alnum:]_]/; 
     2015                { 
     2016                    no strict 'refs'; 
     2017                    *{$typo_package  . '::' . $typo_function} 
     2018                        = *{$package . '::' . $function}; 
     2019                } 
     2020                push @{$TYPO_PACKAGES{$typo_package}}, $typo_function; 
     2021            } 
     2022        } 
     2023 
     2024        $i++; 
     2025    } 
     2026} 
     2027 
     2028sub typo_packages { 
     2029    %TYPO_PACKAGES; 
     2030} 
     2031 
     20321; 
     2033このAcme::Class::TypoSafeはCodeReposに置いてありますので、typoに惑わされることのない安心・快適な泥酔コーディングを目指すPerlハッカーのみなさんに、改善をお願いしたいところであります。というわけで、次ははこべさん、お願いします。 
     2034</description> 
     2035      <dc:date>2008-12-17T15:44:03Z</dc:date> 
     2036      <title>酔っぱらった勢いでコードを書く際に大切なこと</title> 
     2037      <pubDate>Wed, 17 Dec 2008 15:44:03 -0000</pubDate> 
     2038      <content:encoded>&lt;body&gt;&lt;h1&gt;酔っぱらった勢いでコードを書く際に大切なこと&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt;プライベートでコードを書く時は、たいていビールを飲みながらってな毎日のkentaro a.k.a. &lt;a href="http://d.hatena.ne.jp/antipop/"&gt;id:antipop&lt;/a&gt;です。こんにちは。&lt;/p&gt;&lt;p&gt;そんなわけで、ただでさえtypoが多いのに加えて、酔いにより手元はボロボロ。調子良く書いていても、つまらないtypoをいちいち修正してまわっていると、せっかくの気分のいい酔いも覚めてしまうというものです。そこで、コードを書く時には酒を飲まない、という以外の対策を考えてみました。&lt;/p&gt;&lt;h2&gt;とにかく全部ぶっつぶす&lt;/h2&gt;&lt;p&gt;ひとはどうしたところで間違いを犯すものです。酔っぱらっていても酔っぱらってなくても、それは同じ。ならば、あり得る名前をあらかじめ定義してはどうか、と考えました。&lt;/p&gt;&lt;p&gt;たとえば以下のようなクラスを定義したとします。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;package Hoge::Fuga::Piyo; 
     2039use strict; 
     2040use warnings; 
     2041 
     2042# ... (snip) ... 
     2043 
     20441; 
     2045&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このクラスを使う際に、上記したように手元不如意の状態に陥っていると、ついつい以下のように書いたりして、怒られたりします。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;my $obj = Hgeo::Ufag::Poyi-&amp;gt;new; 
     2046&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;こんなことではいつtypoをしてしまうか心配で、あっという間に酔いも覚めてしまうでしょう。&lt;/p&gt;&lt;p&gt;この大変に深刻な問題避けるにはどうしたらいいか。そうです。Hoge::Fuga::Piyoという正しいパッケージ名から得られる、あり得る組合せのクラスをあらかじめ定義してまわれば、たとえ上記のようなコードを書いてしまったとしても、つつがなく、期待通りにスクリプトは動作し、酔い心地を邪魔されることもありません。&lt;/p&gt;&lt;p&gt;というわけで、なんらかの方法でもってHoge::Fuga::Piyoの順列組合せを生成して、その名前を元にパッケージを定義してみようと思い立ちました。さて、どのぐらいの組合せがあるのでしょうか。ここでは、&lt;/p&gt;&lt;ul&gt;&lt;li&gt;パッケージ名に含まれるアルファベットの大文字小文字を考慮しない。&lt;/li&gt;&lt;li&gt;組合せは::で分割された文字列どうしで行われる、という条件を置く。&lt;/li&gt;&lt;li&gt;::で分割された各パートに含まれる文字を全て使う。つまり各パートの文字数は変わらない。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;すると、組合せの数はHoge::Fuga::Piyoの場合、&lt;code&gt;4! * 4! * 4! = 1,000&lt;/code&gt;通りになります。もしパッケージ名がSome::Complicated::Nameのようなものだった場合、&lt;code&gt;4! * 11! * 4! = 6,600&lt;/code&gt;通りなんてな大きな数字になってしまいます。これではダメです……。&lt;/p&gt;&lt;h2&gt;もう少し賢く&lt;/h2&gt;&lt;p&gt;さすがに、あり得るものを全部網羅しようなんて無茶でした。それに上記の条件だと組み合わせに過ぎないので、typoにありがちな隣のキーを押してしまったというような状況を救うことができません。もっと人間の現実にやりがちな間違いに適切に対応した、賢い仕組みが必要です。&lt;/p&gt;&lt;p&gt;そこでCPANを漁ってみると、&lt;a href="http://search.cpan.org/dist/Acme-Tpyo/"&gt;Acme::Tpyo&lt;/a&gt;なんてな、その名前からしてひとを食ったようなモジュールが見つかります。ちなみにTpyoは僕がtypoしたのではなく、モジュール名自体がtypoを表現しています。&lt;/p&gt;&lt;p&gt;これはどんなモジュールかというと、ある文字列を渡すと、わざとtypoした文章を生成して返してくれるというものです。しかも、ただ単にtypoした文字列を返すだけではなく、typingしているひとの性格や能力、その時の状態をエミュレートしてtypoしてくれるというインテリジェントなtypoマシーンなのです。たとえば、typistがキーをどれだけミスタイプしがちか、指の太さ、キータッチの強さ、カフェインや、はたまたアルコールの摂取状況なんてことまで考慮してくれます。まさに、今回の問題を解決するに際して、まさにぴったりの機能を提供してくれるものであるといえます。&lt;/p&gt;&lt;h2&gt;typo safeな環境を作る&lt;/h2&gt;&lt;p&gt;そこで、上述のAcme::Tpyoを用いて、typoに強い環境を作ってみましょう。その際、基本的には「全方位作戦」の方針を踏襲しますが、無制限に候補を羅列してもしかたがないし、また、Acme::Tpyoのインテリジェントなtypo生成能力により現実的にあり得る間違いをかなりしぼれると思わるので、適当な数だけ候補を生成するようにして、大体において役立ちそうというラインで満足するようにしておきましょう。&lt;/p&gt;&lt;p&gt;ここでは&lt;a href="http://svn.coderepos.org/share/lang/perl/Acme-Class-TypoSafe/trunk/"&gt;Acme::Class::TypoSafe&lt;/a&gt;というモジュールを作成してみました。実装の詳細を検討する前に、まずは使い方を見ておきましょう。このモジュールのテストコードを以下に示します。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use strict; 
     2047use warnings; 
     2048use Test::More qw(no_plan); 
     2049use UNIVERSAL::require; 
     2050 
     2051package Some::Complicated::Name; 
     2052use Acme::Class::TypoSafe; 
     2053 
     2054sub new { bless {}, shift } 
     2055sub difficult_to_type_correctly {} 
     2056 
     2057package main; 
     2058 
     2059my %packages = Acme::Class::TypoSafe-&amp;gt;typo_packages; 
     2060for my $package (keys %packages) { 
     2061    my $obj = $package-&amp;gt;new; 
     2062    isa_ok $obj, $package; 
     2063    isa_ok $obj, &amp;apos;Some::Complicated::Name&amp;apos;; 
     2064    can_ok $obj, (&amp;apos;new&amp;apos;, &amp;apos;difficult_to_type_correctly&amp;apos;, @{$packages{$package}}); 
     2065} 
     2066&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ここでは、Some::Complicated::Nameというクラスを定義して、それを使ってコードを書いていこうとしています。Acme::Class::TypoSafeの使い方は上記の通り簡単で、単に&lt;code&gt;use&lt;/code&gt;するだけです。その結果、デフォルトでは100通りのtypoしたらこうなるだろうなというパッケージ名を生成して、それをAcme::Class::TypoSafeを&lt;code&gt;use&lt;/code&gt;したモジュールの子クラスとして定義します。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt; package Some::Complicated::Name; 
     2067use Acme::Class::TypoSafe; 
     2068 
     2069# ... (snip) ... 
     2070 
     2071package main; 
     2072my $foo = Sone::Conplicared::Name-&amp;gt;new; 
     2073my $bar = Sien::Cmopcalired::Nane-&amp;gt;new; 
     2074&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;酔っぱらって手元不如意のままこんなコードを書いても、もう安心です。ちょっとしたtypoぐらい気にかけなくても、各種パラメタの調整具合や、確率的な事情にもよりますが、けっこう拾ってくれるようです。&lt;/p&gt;&lt;h2&gt;さらにtypoしてみる&lt;/h2&gt;&lt;p&gt;ここまでは、パッケージ名についてtypoした場合のことしか考慮していませんでした。typoにおいて更に深刻なのは、パッケージ名よりも書く機会の多いメソッド名でしょう。そこで、Acme::Class::TypoSafeを、メソッド名についても&lt;code&gt;use&lt;/code&gt;元パッケージのメソッド一覧からそれぞれのtypo文字列を生成してエイリアスメソッドを定義するということにしました。&lt;/p&gt;&lt;p&gt;……といいたいところなのですが、この記事を書いている時点では、以下のように実装してみたものの、&lt;code&gt;use&lt;/code&gt;元のメソッド一覧を取得することができず、そのためメソッド名についてはいまも安心できない状況が続いています。&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;package Acme::Class::TypoSafe; 
     2075use strict; 
     2076use warnings; 
     2077use Acme::Tpyo; 
     2078use Class::Inspector; 
     2079 
     2080our $VERSION       = &amp;apos;0.01&amp;apos;; 
     2081our %TYPO_PACKAGES = (); 
     2082 
     2083sub import { 
     2084    my ($class, %args) = @_; 
     2085    my $package = caller; 
     2086    my $keyset  = delete $args{keyset}; 
     2087    my $tpyist  = delete $args{tpyist}; 
     2088    my $count   = delete $args{count} || 100; 
     2089    my $tpyo    = Acme::Tpyo-&amp;gt;new($keyset, $tpyist); 
     2090 
     2091    my $i = 0; 
     2092    while ($i &amp;lt; $count)  { 
     2093        my $typo_package = join &amp;apos;::&amp;apos;, map { 
     2094            my $part = $_; 
     2095            my $typo = $tpyo-&amp;gt;misspell($part); 
     2096            ucfirst(lc($typo)); 
     2097        } split &amp;apos;::&amp;apos;, $package; 
     2098 
     2099        next if $package eq $typo_package           || 
     2100                $typo_package =~ /[^[:alnum:]_\:]/; 
     2101 
     2102        # define typo packages 
     2103        eval &amp;lt;&amp;lt;&amp;quot;EOS&amp;quot;; 
     2104package $typo_package; 
     2105use base qw($package); 
     2106EOS 
     2107        $TYPO_PACKAGES{$typo_package} = []; 
     2108 
     2109        # define typo functions for typo packages 
     2110        for my $function (@{Class::Inspector-&amp;gt;functions($package)}) { 
     2111            warn $function; 
     2112            for (1 .. $count) { 
     2113                my $typo_function = $tpyo-&amp;gt;misspell($function); 
     2114                warn $typo_function; 
     2115                next if $function eq $typo_function        || 
     2116                        $typo_function =~ /[^[:alnum:]_]/; 
     2117                { 
     2118                    no strict &amp;apos;refs&amp;apos;; 
     2119                    *{$typo_package  . &amp;apos;::&amp;apos; . $typo_function} 
     2120                        = *{$package . &amp;apos;::&amp;apos; . $function}; 
     2121                } 
     2122                push @{$TYPO_PACKAGES{$typo_package}}, $typo_function; 
     2123            } 
     2124        } 
     2125 
     2126        $i++; 
     2127    } 
     2128} 
     2129 
     2130sub typo_packages { 
     2131    %TYPO_PACKAGES; 
     2132} 
     2133 
     21341; 
     2135&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このAcme::Class::TypoSafeは&lt;a href="http://svn.coderepos.org/share/lang/perl/Acme-Class-TypoSafe/trunk/"&gt;CodeReposに置いてあります&lt;/a&gt;ので、typoに惑わされることのない安心・快適な泥酔コーディングを目指すPerlハッカーのみなさんに、改善をお願いしたいところであります。&lt;/p&gt;&lt;p&gt;というわけで、次は&lt;a href="http://d.hatena.ne.jp/hakobe932/"&gt;はこべさん&lt;/a&gt;、お願いします。&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
     2136</content:encoded> 
     2137      <dcterms:modified>2008-12-17T15:44:03Z</dcterms:modified> 
     2138      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/17.html</guid> 
     2139    </item> 
     2140    <item> 
     2141      <author>nobody@example.com</author> 
     2142      <dc:creator>nobody@example.com</dc:creator> 
     2143      <link>http://perl-users.jp/articles/advent-calendar/2008/18.html</link> 
     2144      <description>ファイルのすべてを飲み込む方法 原稿を落としたら,すしをおごりにアメリカに行かないといけないとの噂にgkbrしているid:hakobe932です. 932は草津の932です.こんにちは. ファイルの中身をすべて読み込む処理というのは,非常によくある処理です.TIMTOWTDIが信条のPerlでは,ファイルの中身をすべて読み込む方法もたくさんあります.ここでは,どんな方法があるのか紹介いきましょう. 行単位で読み込むもっともシンプルなのは行入力演算子(&lt;&gt;)を使って行毎にデータを読み込み,それを連結する方法です.open my $fh, '&lt;', './inputfile' 
     2145    or die "failed to open: $!"; 
     2146my $content = ''; 
     2147while (my $line = &lt;$fh&gt;) { 
     2148    $content .= $line; 
     2149} 
     2150print $content; 
     2151もう少し工夫して後置whileを使うと1行で書くことができます.open my $fh, '&lt;', './inputfile' 
     2152    or die "failed to open: $!"; 
     2153my $content = ''; 
     2154$content .= $_ while &lt;$fh&gt;; 
     2155print $content; 
     2156行入力演算子はリストコンテキストで評価すると,すべての行のリストが返ってくるので,次のように書くこともできます. open my $fh, '&lt;', './inputfile' 
     2157    or die "failed to open: $!"; 
     2158my $content = join '', &lt;$fh&gt;; 
     2159print $content; 
     2160$/を利用して読み込む行入力演算子でファイルの内容をすべて読み込むのは,シンプルで比較的わかりやすいですが,行を一度保存するのでメモリを食いがちです.もう少し効率の良い方法として$/変数を使うやりかたがあります.グローバル変数$/をローカル化すると行入力演算子でファイルの内容をすべて読み込むことができます. open my $fh, '&lt;', './inputfile' 
     2161    or die "failed to open: $!"; 
     2162my $content = ''; 
     2163{ 
     2164    local $/; 
     2165    $content = &lt;$fh&gt;; 
     2166} 
     2167print $content; 
     2168これでは少しかっこわるいのですが,doブロックを使えばもう少しきれいです.open my $fh, '&lt;', './inputfile' 
     2169    or die "failed to open: $!"; 
     2170my $content = do { local $/; &lt;$fh&gt; }; 
     2171print $content; 
     2172これでコードもずいぶんスッキリしました.しかし,おまじない的なコードで,ぱっとみたときに何をやっているのかわかりにくいですね. ファイルのすべてを飲み込む そこで,ファイルのすべてを飲み込むためにPerl6::Slurpを使いましょう.Perl6::Slurpは名前の通りファイルの内容をすべて飲み込みます. use Perl6::Slurp; 
     2173my $content = slurp './inputfile'; 
     2174print $content; 
     2175Perl6::Slurpでexportされるslurp関数を使えば,おまじない的な部分がなくなって,とってもシンプルでわかりやすいコードが書けます.しかも,ファイルハンドルをopenする手間もへって良いとこづくしですね!他にPath::Classを使うという手もあります. use Path::Class; 
     2176my $inputfile = file('./inputfile'); 
     2177my $content = $inputfile-&gt;slurp; 
     2178print $content; 
     2179Path::Classはslurpするのに使う以外にも,ファイル操作に関する便利なメソッドがたくさん用意されています.モダンなPerlコードでは定番の のファイル操作のモジュールですね.このように,すでにあるモジュールを使うとすっきり簡潔にコードが書けます.モジュールの充実しているPerlの醍醐味かもデスネ.おまけ: readシステムコールで直接読み込むsysread関数をつかえばreadシステムコールを発行して指定サイズ文だけファイルからデータを読み込めます.-s 演算子をファイルハンドルに対して使えばファイルサイズが取れるので,以下のようにすればファイルの内容をすべて読み込むことができます. open my $fh, '&lt;', './inputfile' 
     2180    or die "failed to open: $!"; 
     2181my $content; 
     2182sysread $fh, $content, -s $fh; 
     2183print $content; 
     2184事前にサイズを指定してシステムコールを発行するので,非常に高速なはずです.ただし,生のシステムコールを叩くのでいろいろな例外事項の対処を自分でしないといけないため,あまりおすすめできません! まとめというわけで,いろいろな方法でファイルの中身をすべて読み込んで見ました.多くの選択肢があってなかなかPerlらしい感じですね.わかりやすさや,覚えやすさ,書いているプログラムの性質などに合わせて,良さそうなのを選べば良いと思います.個人的には,Perl6::Slurpや$/を使った方法をよく使います.これからは,Path::Classを使うのがオシャレかもしれませんね.もし,このほかにもファイルを飲み込む方法があればぜひ教えてクダサイ.といわけで,次はid:secondlifeさんよろしくお願いします. 
     2185</description> 
     2186      <dc:date>2008-12-18T14:45:57Z</dc:date> 
     2187      <title>ファイルのすべてを飲み込む方法</title> 
     2188      <pubDate>Thu, 18 Dec 2008 14:45:57 -0000</pubDate> 
     2189      <content:encoded>&lt;body&gt;&lt;h1&gt;ファイルのすべてを飲み込む方法&lt;/h1&gt;&lt;div class="section"&gt;&lt;p&gt; 原稿を落としたら,すしをおごりにアメリカに行かないといけないとの噂にgkbrしている&lt;a href="http://d.hatena.ne.jp/hakobe932"&gt;id:hakobe932&lt;/a&gt;です. 932は草津の932です.こんにちは. &lt;/p&gt;&lt;p&gt;ファイルの中身をすべて読み込む処理というのは,非常によくある処理です.TIMTOWTDIが信条のPerlでは,ファイルの中身をすべて読み込む方法もたくさんあります.ここでは,どんな方法があるのか紹介いきましょう. &lt;/p&gt;&lt;h2&gt;行単位で読み込む&lt;/h2&gt;&lt;p&gt;もっともシンプルなのは行入力演算子(&amp;lt;&amp;gt;)を使って行毎にデータを読み込み,それを連結する方法です.&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2190    or die &amp;quot;failed to open: $!&amp;quot;; 
     2191my $content = &amp;apos;&amp;apos;; 
     2192while (my $line = &amp;lt;$fh&amp;gt;) { 
     2193    $content .= $line; 
     2194} 
     2195print $content; 
     2196&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;もう少し工夫して後置whileを使うと1行で書くことができます.&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2197    or die &amp;quot;failed to open: $!&amp;quot;; 
     2198my $content = &amp;apos;&amp;apos;; 
     2199$content .= $_ while &amp;lt;$fh&amp;gt;; 
     2200print $content; 
     2201&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;行入力演算子はリストコンテキストで評価すると,すべての行のリストが返ってくるので,次のように書くこともできます. &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2202    or die &amp;quot;failed to open: $!&amp;quot;; 
     2203my $content = join &amp;apos;&amp;apos;, &amp;lt;$fh&amp;gt;; 
     2204print $content; 
     2205&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;$/を利用して読み込む&lt;/h2&gt;&lt;p&gt;行入力演算子でファイルの内容をすべて読み込むのは,シンプルで比較的わかりやすいですが,行を一度保存するのでメモリを食いがちです.もう少し効率の良い方法として$/変数を使うやりかたがあります.&lt;/p&gt;&lt;p&gt;グローバル変数$/をローカル化すると行入力演算子でファイルの内容をすべて読み込むことができます. &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2206    or die &amp;quot;failed to open: $!&amp;quot;; 
     2207my $content = &amp;apos;&amp;apos;; 
     2208{ 
     2209    local $/; 
     2210    $content = &amp;lt;$fh&amp;gt;; 
     2211} 
     2212print $content; 
     2213&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これでは少しかっこわるいのですが,doブロックを使えばもう少しきれいです.&lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2214    or die &amp;quot;failed to open: $!&amp;quot;; 
     2215my $content = do { local $/; &amp;lt;$fh&amp;gt; }; 
     2216print $content; 
     2217&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これでコードもずいぶんスッキリしました.しかし,おまじない的なコードで,ぱっとみたときに何をやっているのかわかりにくいですね. &lt;/p&gt;&lt;h2&gt;ファイルのすべてを飲み込む&lt;/h2&gt;&lt;p&gt; そこで,ファイルのすべてを飲み込むために&lt;a href="http://search.cpan.org/perldoc?Perl6::Slurp"&gt;Perl6::Slurp&lt;/a&gt;を使いましょう.Perl6::Slurpは名前の通りファイルの内容をすべて飲み込みます. &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use Perl6::Slurp; 
     2218my $content = slurp &amp;apos;./inputfile&amp;apos;; 
     2219print $content; 
     2220&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Perl6::Slurpでexportされるslurp関数を使えば,おまじない的な部分がなくなって,とってもシンプルでわかりやすいコードが書けます.しかも,ファイルハンドルをopenする手間もへって良いとこづくしですね!&lt;/p&gt;&lt;p&gt;他に&lt;a href="http://search.cpan.org/perldoc?Path::Class"&gt;Path::Class&lt;/a&gt;を使うという手もあります. &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;use Path::Class; 
     2221my $inputfile = file(&amp;apos;./inputfile&amp;apos;); 
     2222my $content = $inputfile-&amp;gt;slurp; 
     2223print $content; 
     2224&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Path::Classはslurpするのに使う以外にも,ファイル操作に関する便利なメソッドがたくさん用意されています.モダンなPerlコードでは定番の のファイル操作のモジュールですね.&lt;/p&gt;&lt;p&gt;このように,すでにあるモジュールを使うとすっきり簡潔にコードが書けます.モジュールの充実しているPerlの醍醐味かもデスネ.&lt;/p&gt;&lt;h2&gt;おまけ: readシステムコールで直接読み込む&lt;/h2&gt;&lt;p&gt;sysread関数をつかえばreadシステムコールを発行して指定サイズ文だけファイルからデータを読み込めます.-s 演算子をファイルハンドルに対して使えばファイルサイズが取れるので,以下のようにすればファイルの内容をすべて読み込むことができます. &lt;/p&gt;&lt;pre class="lang-perl"&gt;&lt;code&gt;open my $fh, &amp;apos;&amp;lt;&amp;apos;, &amp;apos;./inputfile&amp;apos; 
     2225    or die &amp;quot;failed to open: $!&amp;quot;; 
     2226my $content; 
     2227sysread $fh, $content, -s $fh; 
     2228print $content; 
     2229&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;事前にサイズを指定してシステムコールを発行するので,非常に高速なはずです.ただし,生のシステムコールを叩くのでいろいろな例外事項の対処を自分でしないといけないため,あまりおすすめできません! &lt;/p&gt;&lt;h2&gt;まとめ&lt;/h2&gt;&lt;p&gt;というわけで,いろいろな方法でファイルの中身をすべて読み込んで見ました.多くの選択肢があってなかなかPerlらしい感じですね.わかりやすさや,覚えやすさ,書いているプログラムの性質などに合わせて,良さそうなのを選べば良いと思います.個人的には,Perl6::Slurpや$/を使った方法をよく使います.これからは,Path::Classを使うのがオシャレかもしれませんね.&lt;/p&gt;&lt;p&gt;もし,このほかにもファイルを飲み込む方法があればぜひ教えてクダサイ.&lt;/p&gt;&lt;p&gt;といわけで,次は&lt;a href="http://d.hatena.ne.jp/secondlife"&gt;id:secondlife&lt;/a&gt;さんよろしくお願いします.&lt;/p&gt;&lt;/div&gt;&lt;/body&gt; 
     2230</content:encoded> 
     2231      <dcterms:modified>2008-12-18T14:45:57Z</dcterms:modified> 
     2232      <guid isPermaLink="false">tag:perl-users.jp,2006:http://perl-users.jp/articles/advent-calendar/2008/18.html</guid> 
    18112233    </item> 
    18122234  </channel>