<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>perl-mongers.org</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/" />
    <link rel="self" type="application/atom+xml" href="http://perl-mongers.org/atom.xml" />
    <id>tag:perl-mongers.org,2008-05-19://1</id>
    <updated>2010-06-18T05:59:47Z</updated>
    <subtitle>Yet Another Perl Mongers</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>

<entry>
    <title>実用！ PerlでコマンドラインからTwitter投稿（OAuth対応）</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2010/06/_perltwitteroauth.html" />
    <id>tag:perl-mongers.org,2010://1.96</id>

    <published>2010-06-09T17:06:00Z</published>
    <updated>2010-06-18T05:59:47Z</updated>

    <summary>まいど！ 畑違いの業界（印刷屋さんです）からこんにちは！ CLです。 最近Win...</summary>
    <author>
        <name>CL</name>
        <uri>http://blog.dtpwiki.jp/dtp/</uri>
    </author>
    
    <category term="nettwitter" label="Net::Twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="oauth" label="OAuth" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>まいど！ 畑違いの業界（印刷屋さんです）からこんにちは！ CLです。</p>
<blockquote><p>最近WindowsからLinuxへログインして作業していることが多いんですけれども、なんかつぶやきたくなったときにこんなの。Twitterにポスト。Net::Twitterモジュールを使います。</p></blockquote>
<p>と書いたのが2年前。</p>
<p><a href="http://perl-mongers.org/2008/06/_perltwitter.html">実用！ PerlでコマンドラインからTwitter投稿 - perl-mongers.org</a></p>
<p>今は2010年の6月なんですけれども、6月いっぱいで、Twitter APIのBASIC認証ができなくなってしまうということで、前書いた記事も結構のアクセス量があるみたいなので、改訂版として書いてみようと思います。</p>

<p><strong>（2010-06-18追記）<br />
<a href="http://blog.twitter.jp/2010/06/twitter-api-oauth.html">Twitterブログ: Twitter APIデベロッパー・コミュニティへのお知らせ (OAuthへの移行に関しての期限延長)</a></strong></p>
<blockquote><p><strong>以前、ベーシック認証への対応を2010年6月30日をもって終了し、OAuthに移行する予定であることを発表しましたが、このたびOAuthへの移行の期限を2010年8月16日まで延長ことにしました。 2010年8月16日から段階的にベーシック認証への対応を停止します。</strong></p></blockquote>

<p>今回の流れは、</p>
<ul>
  <li><strong>Twitterでアプリ登録をする</strong>（今回追加！）</li>
  <li>とりあえず投稿できるスクリプトを作ってみる</li>
  <li>コマンドラインから投稿できるものにグレードアップ</li>
</ul>
<p>となっています。</p>
<p>※<strong>いまどきのNet::Twitterは、CPANを使い、イチからインストールすると、1時間ぐらいかかります</strong>。僕は、Amazon EC2では、既にNet::Twitterをインストール済みのAMIを用意しています。</p>]]>
        <![CDATA[<h4>Twitterでアプリ登録をする</h4>
<p>既に、Twitterのアカウントをとっているのであれば、とても簡単にアプリ登録ができます。</p>
<p>１．ホーム画面の下の方にAPIとあるので、選択します。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-01.html"><img alt="oauth-01.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-01-thumb-710x394.png" style="" /></a></span>
<p><br /></p>
<p>２．「Create cool applications!」とかいうページが出ます。クールか......。ともかく、「②Register an app」を選択します。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-02.html"><img alt="oauth-02.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-02-thumb-710x474.png" style="" /></a></span>
<p><br /></p>
<p>３．「アプリケーション登録申請」画面が出ます。申請出すと無条件に登録されますし、後から設定は変更できますけれども、順番に「アプリケーション名」「アプリケーションの説明」「アプリケーションのウェブサイトURL」「所属会社／団体」を考えておきましょう。今回は、以下のアプリを作りことにしました。</p>
<ul>
  <li><strong>アプリケーション名</strong><ul>
    <li>ちんまん亭</li>
    </ul>
  </li>
  <li><strong>アプリケーションの説明</strong><ul>
    <li>コマンドラインから投稿できるTwitterクライアントです</li>
    </ul>
  </li>
  <li><strong>アプリケーションウェブサイト</strong><ul>
    <li>http://perl-mongers.org/2010/06/_perltwitteroauth.html</li>
    </ul>
  </li>
  <li><strong>所属会社／団体</strong><ul>
    <li>斜陽業界</li>
    </ul>
  </li>
</ul>
<p>「ラーメン大陸」というクライアント名に倣い、類似した名前にしました。</p>
<p>あと、「アプリケーションの種類」は、自分だけ使うんであれば、「クライアントアプリケーション」でいいと思います。</p>
<p>「Default Access type」は、「Read &amp; Write」にしておきましょう。</p>
<p>全部入れ終わったら、「アプリケーションを登録する」ボタンを選択します。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-03.html"><img alt="oauth-03.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-03-thumb-710x890.png" style="" /></a></span>
<p><br /></p>
<p>４．Twitter API使用規約が出ますので、内容を確認の上「I Accept（同意）」を選択します。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-04.html"><img alt="oauth-04.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-04-thumb-710x509.png" style="" /></a></span>
<p><br /></p>
<p>５．はい、アプリケーションはできました！Consumer keyとConsumer Secretを控えておきます。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-05.html"><img alt="oauth-05.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-05-thumb-710x971.png" style="" /></a></span>
<p><br /></p>
<p>６．次に、このアプリケーションを使ってアクセスするために、自分のアカウントでのAccess Tokenを取得します。右側のサイドバーに、「My Access Token」つうのがありますので、これを選択します。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="oauth-06.png" class="mt-image-none" src="http://perl-mongers.org/oauth-06.png" style="" /></span>
<p><br /></p>
<p>７．自分のアクセストークンが表示されますので、コピペでもしてメモっておきます。ちなみに、<strong>このアクセストークンは、自分のID、パスワードの代わりになりますので人に教えないでください</strong>。今回の例では、アクセストークンは適当なものに変えてあります。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-07.html"><img alt="oauth-07.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-07-thumb-710x509.png" style="" /></a></span>
<p><br /></p>
<p>８．最後に、今回作ったアプリの設定を変えたくなった時の話をしておきますが、上部に「Your apps」という項目がありますので、ここを選択しますと、作ったアプリ一覧が表示されます。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-08.html"><img alt="oauth-08.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-08-thumb-710x509.png" style="" /></a></span>
<p><br /></p>
<p>おめでとうございます！ これで、OAuthでTwitterにポストできる準備が整いました。</p>
<h4>とりあえず投稿できるスクリプトを作ってみる</h4>
<p>まず、固定文字列だったらこんな感じで。「もへもへ」という文字列を投げます。それぞれのキーは自分のを使おう。</p>
<p>Filename:twit_test.pl　(UTF-8で)</p>
<pre class="prettyprint">
#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Net::Twitter;
my $twit = Net::Twitter-&gt;new(
    traits =&gt; [qw/API::REST OAuth WrapError/],
    consumer_key    =&gt; &#39;o3ca3zChEnEK3sEKM6Uw&#39;,
    consumer_secret =&gt; &#39;LU69ATliCLFWalIt1Q8aR7gFYcQuG9hqTOOPFNVNU&#39;,
    ssl =&gt; 1,
);
$twit-&gt;access_token       (&#39;12345678-i9QgwXsXhRj3A1mcX9ok8egM68dJcS26r3lKBaVg8&#39;);
$twit-&gt;access_token_secret(&#39;joCdbaccz7PKmw7VLsFFgsW2JAgOHk4cEW7Src8zH&#39;);
$twit-&gt;update(&#39;もへもへ&#39;);
exit;
__END__</pre>

<p>実行すると、Twitterに投稿されるはずです。文字化けしてたら、おそらく文字エンコーディングがUTF-8以外です。UTF-8で保存し直すか、Encodeモジュールで適切に変換してあげましょう。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-09.html"><img alt="oauth-09.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-09-thumb-710x275.png" style="" /></a></span>
<p><br /></p>
<h4>コマンドラインから投稿できるものにグレードアップ</h4>
<p>上のスクリプトを生かして、コマンドラインからの文字列を投稿するスクリプトに改造します。今回はタイプ量減らしたいので、コンソールがUTF-8の場合に限定。他の環境の場合、Encodeモジュールやらなにやら使用のこと。</p>
<p>Filename: twitter</p>
<pre class="prettyprint">
#!/usr/bin/perl

use strict;
use warnings;
use Encode;
use utf8;
use Net::Twitter;
my $twit = Net::Twitter-&gt;new(
    traits =&gt; [qw/API::REST OAuth WrapError/],
    consumer_key    =&gt; &#39;o3ca3zChEnEK3sEKM6Uw&#39;,
    consumer_secret =&gt; &#39;LU69ATliCLFWalIt1Q8aR7gFYcQuG9hqTOOPFNVNU&#39;,
    ssl =&gt; 1,
);
$twit-&gt;access_token       (&#39;12345678-i9QgwXsXhRj3A1mcX9ok8egM68dJcS26r3lKBaVg8&#39;);
$twit-&gt;access_token_secret(&#39;joCdbaccz7PKmw7VLsFFgsW2JAgOHk4cEW7Src8zH&#39;);
$twit-&gt;update( decode_utf8($_) ) for @ARGV;
exit;
__END__</pre>

<p>上記twitterというファイルに実行権限を与えておいて、個人用実行ファイルを置くディレクトリ（$HOME/bin とかにpath通しておくと便利）に入れるとかしておくと、</p>
<pre>
$ twitter エロス</pre>

<p>とか</p>
<pre>
$ twitter &#39;エロス カワユス&#39;</pre>

<p>とかで投稿できます。</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://perl-mongers.org/assets_c/2010/06/oauth-10.html"><img alt="oauth-10.png" class="mt-image-none" src="http://perl-mongers.org/assets_c/2010/06/oauth-10-thumb-710x399.png" style="" /></a></span>
<p><br /></p>
<p>今回のスクリプトを改造して、定期的にビーコン打ち出すとか、作業が終わったらnotify出すとか応用できます。僕は他のユーザからのリプライにて目覚ましツイート時間を設定できるbotを作ったりしていますよ。</p>
<p>※調子こいて投稿しまくっていると連投制限に引っかかるみたいなので注意しましょう。</p>]]>
    </content>
</entry>

<entry>
    <title>Moose &amp; Mouse基本文法最速マスター/The Fastest Way to Mastering Moose &amp; Mouse</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html" />
    <id>tag:perl-mongers.org,2010://1.95</id>

    <published>2010-02-17T16:47:31Z</published>
    <updated>2010-02-20T23:54:35Z</updated>

    <summary><![CDATA[Moose &amp; Mouse基本文法最速マスター/The Fastest ...]]></summary>
    <author>
        <name>gardejo</name>
        <uri>http://blog.eorzea.asia/</uri>
    </author>
    
    <category term="moose" label="Moose" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="oop" label="oop" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<h2><code>Moose</code> &amp; <code>Mouse</code>基本文法最速マスター/The Fastest Way to Mastering <code>Moose</code> &amp; <code>Mouse</code></h2>

<p>はじめまして。gardejoこと守屋と申します。</p>

<p>この文書はPerlの拡張モジュール<a href="http://search.cpan.org/perldoc?Moose"><code>Moose</code></a>によるポストモダンオブジェクト指向プログラミングの文法や作法などを簡易的にまとめたものです。Perl5の基本文法に習熟していて、かつ、言語を問わず一般的な<a href="http://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91">オブジェクト指向</a>についての知識がある人を想定読者としています。</p>

<p>内容は<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#0.98"><code>Moose</code>のバージョン<code>0.98</code></a>に基づきます。<a href="http://search.cpan.org/perldoc?Mouse"><code>Mouse</code></a>のバージョン<code>0.50_01</code>時点の内容も付記しています。</p>

<!-- Moose用語は可能な限り元の英語を併記していますが、Moose用語以外の英語への訳出はいい加減です。ごめんなさい。 -->

<p>誤っている点, ご不明な点, 冗長すぎてかえって初学者を混乱させかねないため削除すべき点などがありましたら、コメントやトラックバックなどでお寄せいただければ幸いです。適宜改訂します。</p>

<h3><span id="table_of_contents">目次/Table of Contents</span></h3>

<!--

目次が膨大すぎるとかえって読む気が失せそうなので、簡略版の目次だけにしました。



86ee43a60697c77b3d15d48c149e213e


-->

<ul>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#classes">クラス/Classes</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#roles">ロール/Roles</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#sugar_functions">シュガー関数/Sugar Functions</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#attribute_constructor_options">アトリビュート構築オプション/Attribute Constructor Options</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#types">型/Types</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#delegation">委譲/Delegation</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#construction_and_destruction_of_instances">インスタンスの生成と破棄/Construction and Destruction of Instances</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#other_tidbits">その他の内容の触り/Other Tidbits</a></li>
<li><a href="http://perl-mongers.org/2010/02/the-fastest-way-to-mastering-moose-and-mouse.html#see_also">情報源など/See Also</a></li>
</ul>]]>
        <![CDATA[<h3><span id="classes">クラス/Classes</span></h3>

<pre><code>package My::Class;
use Moose;
</code></pre>

<p>パッケージを<code>Moose</code>に基づいたクラスにします。</p>

<pre><code>use URI;                            # Mooseに基づかないクラスのロード
my $uri = URI-&gt;new;                 # クラスのインスタンスの生成

use My::Class;                      # Mooseに基づいたクラスのロード
my $my_instance = My::Class-&gt;new;   # クラスのインスタンスの生成
</code></pre>

<p><code>Moose</code>に基づいたクラスは外部からは（<code>Moose</code>クラスであることを意識せずに）伝統的なPerl5クラスと同様に取り扱えます。</p>

<h4><span id="turning_on_pragmas_and_importing_sugar_functions">プラグマの有効化とシュガー関数のインポート/Turning on Pragmas and Importing Sugar Functions</span></h4>

<p><code>use Moose;</code>すると、<a href="http://search.cpan.org/perldoc?strict"><code>strict</code></a>と<a href="http://search.cpan.org/perldoc?warnings"><code>warnings</code></a>プラグマが有効になる他、クラスを設計するための<a href="http://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87">構文糖</a><span class="en">/syntax sugar</span>である各種のシュガー関数<span class="en">/sugar functions</span>や<a href="http://search.cpan.org/perldoc?Carp"><code>Carp::confess()</code></a>, <a href="http://search.cpan.org/perldoc?Scalar::Util"><code>Scalar::Util::blessed()</code></a>がインポートされます。</p>

<h4><span id="class_has_attributes">アトリビュート/Attributes</span></h4>

<p>クラスは複数のアトリビュート<span class="en">/attributes</span>を持つことができます。これはクラスの状態<span class="en">/state</span>を示すものです。伝統的なPerl5クラスに於いては<code>bless</code>されたハッシュに相当します。C++やJavaのメンバー変数に相当するものです。</p>

<blockquote>
  <p>cf. <a href="#attribute_installation"><code>has</code></a></p>
</blockquote>

<p>なお、Perl 5.6.0以降の「サブルーチンアトリビュート」<span class="en">/subroutine attributes</span>のことではありません。</p>

<h4><span id="class_implements_methods">メソッド/Methods</span></h4>

<p>クラスは複数のメソッド<span class="en">/methods</span>を実装することができます。これはクラスの振る舞い<span class="en">/behavior</span>を示すものです。</p>

<pre><code>sub foo { my ($self, @args) = @_; ... }
</code></pre>

<p>メソッドは通常のPerl5構文の通りに記述します。</p>

<h4><span id="class_extends_superclasses">スーパークラス/Superclasses</span></h4>

<p>クラスは複数のスーパークラス<span class="en">/superclasses</span>を継承<span class="en">/inherit</span>することができます。</p>

<blockquote>
  <p>cf. <a href="#class_inheritance"><code>extends</code></a></p>
</blockquote>

<p>非<code>Moose</code>クラスを継承する場合、<a href="http://search.cpan.org/perldoc?MooseX::NonMoose"><code>MooseX::NonMoose</code></a>を利用することを推奨します。</p>

<h4><span id="class_consumes_roles">ロール/Roles</span></h4>

<p>クラスは複数のロール<span class="en">/roles</span>を消費<span class="en">/consume</span>することができます。</p>

<blockquote>
  <p>cf. <a href="#consuming_roles"><code>with</code></a>, <a href="#roles">ロール/Roles</a></p>
</blockquote>

<h3><span id="roles">ロール/Roles</span></h3>

<pre><code>package My::Role;
use Moose::Role;
</code></pre>

<p>パッケージを<code>Moose::Role</code>に基づいたロールにします。</p>

<p>ロールとは、「APIで何ができるか(<code>does</code>)」に着目した実装方法です。スーパークラスの継承<span class="en">/inheritance</span>による、「クラスが何であるか(<code>isa</code>)」に着目した実装方法よりも柔軟に、アトリビュート, インターフェース, メソッドを実装できます。</p>

<p>クラスにメソッドが生えていることを要求する<code>requires</code>はJavaのインターフェース<span class="en">/interfaces</span>と同様の概念です。ただし、<code>Moose</code>のロールにはアトリビュートや実際のメソッドも実装できるところが違いです。</p>

<p>ロールにメソッドを定義して、そのロールをクラスで消費することで、クラスにメソッドが生えているように取り扱えます。これはRubyのミックスイン<span class="en">/mix-in</span>と同様の概念です。</p>

<p>これにより、継承ツリーに悩まされることなくオブジェクト指向プログラミングを行えますので、<a href="http://mt.endeworks.jp/d-6/">lestrratさん</a>は<a href="http://mt.endeworks.jp/d-6/2008/08/moose-is-a-revolution.html">「オブジェクト指向の革命」</a>だと宣言しています。</p>

<p>有効化されるプラグマやエクスポートされるシュガー関数は<a href="#turning_on_pragmas_and_importing_sugar_functions"><code>use Moose;</code></a>の場合とほぼ同じです。<a href="#class_inheritance"><code>extends</code></a>はクラスでのみ使え、<a href="#consuming_roles"><code>requires</code></a>はロールでのみ使えます。</p>

<blockquote>
  <p>cf. <a href="#consuming_roles"><code>with</code></a>, <a href="#interfaces"><code>requires</code></a></p>
</blockquote>

<h3><span id="sugar_functions">シュガー関数/Sugar Functions</span></h3>

<p><code>Moose</code>クラスと<code>Moose</code>ロールで使用可能なシュガー関数は以下の通りです。</p>

<h4><span id="attribute_installation">アトリビュートの設定/Attribute Installation</span></h4>

<pre><code>has $attribute_name =&gt; %option;
</code></pre>

<p>クラスにアトリビュート<span class="en">/attributes</span>を設定するシュガー関数。</p>

<blockquote>
  <p>cf. <a href="#attribute_constructor_options">アトリビュート構築オプション/Attribute Constructor Options</a></p>
</blockquote>

<pre><code>has [ @attribute_names ] =&gt; %option;
</code></pre>

<p>複数のアトリビュートをまとめて設定することもできます。</p>

<pre><code>has "+$attribute_name" =&gt; %option;
</code></pre>

<p>継承したスーパークラスや消費したロールに存在するアトリビュートの設定を拡張します。</p>

<p>ただし、むやみな上書きは（特に<a href="#type_constraints_and_coercions"><code>isa</code></a>による型制約の上書きは）クラスやロールのAPIを崩すので、避ける方が賢明とされています。</p>

<h4><span id="class_inheritance">クラスの継承/Class Inheritance</span></h4>

<pre><code>extends @superclasses;
</code></pre>

<p>クラスにスーパークラス<span class="en">/superclasses</span>を継承<span class="en">/inherit</span>させるシュガー関数。</p>

<p>伝統的なPerl5オブジェクト指向プログラミングに於ける<code>use base @superclasses</code>構文の代わりに使います。<del datetime="2010-02-21T08:54:35+09:00"><code>@ISA</code>を再設定しないことが<code>use base</code>との違いです。</del></p>

<p>このシュガー関数はクラスにしか記述できません。つまり、ロールには記述できません。</p>

<h4><span id="consuming_roles">ロールの消費/Consuming Roles</span></h4>

<pre><code>with @roles;
</code></pre>

<p>クラスにロール<span class="en">/roles</span>を消費<span class="en">/consume</span>させるシュガー関数。</p>

<p>ロールを<code>with</code>した場所に当該ロールのソースをコピー&amp;ペーストしたかのように動作します。</p>

<p>ロールの中で別のロールを<code>with</code>することもできます。</p>

<blockquote>
  <p>cf. <a href="#roles">ロール/Roles</a></p>
</blockquote>

<pre><code>with $role =&gt; { %option };
</code></pre>

<p>ロールの消費時にオプションを与えることもできます。</p>

<h4><span id="interfaces">インターフェース/Interfaces</span></h4>

<pre><code>requires @methods;
</code></pre>

<p>ロールを<code>with</code>で消費<span class="en">/consume</span>するクラスに於いて、<code>@methods</code>のメソッドが呼び出せることを要求するシュガー関数。</p>

<p>このシュガー関数はロールにしか記述できません（クラスには記述できません）。</p>

<blockquote>
  <p>cf. <a href="#roles">ロール/Roles</a></p>
</blockquote>

<h4><span id="method_modifiers">メソッドモディファイヤー/Method Modifiers</span></h4>

<pre><code>before @method_names =&gt; sub { my ($self, @args) = @_; ... };
after  @method_names =&gt; sub { my ($self, @args) = @_; ... };
</code></pre>

<p>継承したスーパークラスや消費したロールに存在するメソッドを修飾するシュガー関数。修飾されたメソッドの前(<code>before</code>)や後(<code>after</code>)に動かす処理をコードリファレンスで定義します。</p>

<p><code>before</code>のコードリファレンス内では修飾されたメソッドへの引数が、<code>after</code>のコードリファレンス内では修飾されたメソッドからの戻り値が、それぞれ無視されます。それらを編集したい場合には<code>around</code>を使ってください。</p>

<pre><code>around @method_names =&gt; sub { my ($next, $self, @args) = @_; ...; my @retun_values = $self-&gt;$next(@args); ... };
</code></pre>

<p>メソッドを修飾するシュガー関数の一つ。修飾されたメソッドの前後で動かす処理をコードリファレンスで定義します。</p>

<p>コードリファレンスからは修飾されたメソッドを<code>$next</code>で呼べます。修飾されたメソッドの引数と戻り値はコードリファレンス内で編集することもできます。<code>$next</code>を呼ばなければ修飾されたメソッドは呼ばれません。</p>

<pre><code>before qr{ $method_name_pattern } =&gt; sub { ... };   # Moose 0.45+, Mouse 0.50_01+, only in a class
around [ @method_names ] =&gt; sub { ... };            # Moose 0.95+
</code></pre>

<p>上記のように修飾するメソッド名を指定することもできます。正規表現は<a href="http://perl-mongers.org/2008/05/moosearound_modifier.html">dannさんの素敵なパッチ</a>によるものです。</p>

<pre><code>before 2, before 1,
    around 2, around 1,
        wrapped method,
    around 1, around 2,
after 1, after 2
</code></pre>

<p>修飾されたメソッドは<code>before</code>, <code>around</code>, <code>after</code>の順番に修飾されます。複数修飾した場合には、修飾されたメソッドに「近い」ものからクラス継承順やロール修飾順に修飾されます。</p>

<pre><code>override $method_name =&gt; sub { my ($self, @args) = @_; ...; super(); ...; };
</code></pre>

<p>メソッドを修飾するシュガー関数の一つ。継承したスーパークラスに存在するメソッドを明示的にオーバーライド<span class="en">/override</span>します。消費したロールで実装されているメソッドは<code>override</code>できません。</p>

<p>コードリファレンスからは修飾されたメソッドを<code>super()</code>で呼べます。その際の引数は不要です。修飾されたメソッドへも(<code>$self, @args</code>)の引数が渡ります。<code>$self-&gt;SUPER::method(@args);</code>とほぼ同様ですが、<code>@args</code>を編集できない点が異なります。</p>

<p>伝統的なPerl5オブジェクト指向プログラミングのように、<code>sub $method_name { ... }</code>のようにスーパークラスやロールにあるメソッドと同名のメソッドを単に実装しても暗黙的にオーバーライドできます。</p>

<pre><code>augment $method_name =&gt; sub { my ($self, @args) = @_; ...; inner(); ...; };
</code></pre>

<p>メソッドを修飾するシュガー関数の一つで、<code>override</code>および<code>super()</code>と逆の動作をします。</p>

<p>コードリファレンスからはサブクラス<span class="en">/subclasses</span>のメソッドを<code>inner()</code>で呼べます。引数の取り扱いも<code>around</code>に於ける<code>super()</code>と同様です。</p>

<p>保守開発でさらなるサブクラスを作成しうることに鑑みると、最末端クラスでも<code>inner()</code>を呼んでおくと手堅いです（最末端での<code>inner()</code>は何も処理しません）。</p>

<h3><span id="attribute_constructor_options">アトリビュート構築オプション/Attribute Constructor Options</span></h3>

<p><a href="#attribute_installation"><code>has $attribute_name =&gt; %option</code></a>のオプションについて、<code>is</code>以外の指定は任意です（<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.84"><code>Moose 0.84</code></a>未満のバージョンでは、全てのオプションが任意です）。また、一部のオプションは排他指定であったり、別のオプションを一緒に指定する必要があります。</p>

<p>なお、未知の（綴りを間違えた）キーを指定すると、警告が出ます（<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.84"><code>Moose 0.84</code></a>以降, <a href="http://cpansearch.perl.org/dist/Mouse/Changes"><code>Mouse 0.50_01</code></a>以降）。</p>

<p><a href="http://search.cpan.org/search?query=MooseX::&amp;mode=module"><code>MooseX::*</code></a>拡張モジュールなどにより、アトリビュートのオプションも拡張できます。</p>

<blockquote>
  <p>cf. <a href="http://blog.eorzea.asia/2009/10/post_73.html">Mooseアトリビュートのオプション指定順についての私案</a> : あくまでネタです。</p>
</blockquote>

<h4><span id="attribute_extension">アトリビュートの拡張/Attribute Extension</span></h4>

<pre><code>metaclass =&gt; $metaclass_name
</code></pre>

<p>アトリビュートをメタクラス<span class="en">/metaclasses</span>によって拡張します。<code>$metaclass</code>は一つしか指定できません。</p>

<p>完全修飾パッケージ名<code>Moose::Meta::Attribute::Custom::$metaclass_name</code>の<code>$metaclass_name</code>の文字列を指定します。</p>

<pre><code>traits =&gt; [ @trait_names ]
</code></pre>

<p>アトリビュートを<code>@trait_names</code>のトレート<span class="en">/traits</span>によって拡張します。</p>

<p>完全修飾パッケージ名<code>Moose::Meta::$kind::Custom::Trait::$trait_name</code>の<code>$trait_name</code>の文字列を指定します。</p>

<p><a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.89_01"><code>Moose 0.89_01</code></a>以降では<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Array"><code>Array</code></a>などのネイティブトレートが組み込まれています。</p>

<h4><span id="accessor_methods_generation">アクセッサーメソッドの生成/Accessor Methods Generation</span></h4>

<pre><code>is =&gt; 'rw'
is =&gt; 'ro'
is =&gt; 'bare'
</code></pre>

<p>読み書き両用(<code>rw</code>: read-write)または読み取り専用(<code>ro</code>: read only)のアクセッサーメソッド<span class="en">/accessor method</span>をクラスへ生成します。メソッド名は$attribute_nameと同じです。</p>

<p><code>is</code>オプションがないとアクセッサーメソッドは生成されません。<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.84"><code>Moose 0.84</code></a>以降では警告が出るので、明示的に<code>is =&gt; 'bare'</code>を指定する必要があります。</p>

<p><code>is</code>はアクセッサーメソッドの生成のみを司っています。アトリビュートに「書き込み禁止フラグ」のようなものがあるわけではありません<!-- （多分......） -->。従って、<code>is =&gt; 'ro'</code>としても<code>writer</code>で書き込みメソッドを別途指定すれば、アトリビュートへの書き込み手段が存在することになります。</p>

<p>クラス外部へ晒す内部実装は少ない方がよいため、必要に迫られない限りは<code>'ro'</code>や<code>'bare'</code>と指定しておくと手堅いです。</p>

<pre><code>accessor =&gt; $accessor_method_name
</code></pre>

<p>メソッド名を明示的に指定して、アクセッサーメソッドをクラスへ生成します。引数なしでは読み取りメソッドとして働き、引数ありでは書き込みメソッドとして働きます。<code>is</code>は<code>'rw'</code>でなくてはなりません。</p>

<pre><code>reader =&gt; $reader_method_name
</code></pre>

<p>メソッド名を明示的に指定して、読み取りメソッド<span class="en">/reader method</span>をクラスへ生成します。</p>

<pre><code>writer =&gt; $writer_method_name
</code></pre>

<p>メソッド名を明示的に指定して、書き込みメソッド<span class="en">/writer method</span>をクラスへ生成します。</p>

<p><code>is</code>で<code>'ro'</code>と指定しても、<code>writer</code>を指定した場合には、書き込みメソッドが存在することになります。<code>has 'foo' =&gt; (is =&gt; 'ro', writer =&gt; '_foo')</code>で、書き込みメソッド名を（先頭にアンダースコア<code>_</code>を付けることによって）慣習的隠蔽状態にするなどの利用法があります。<a href="#constructor_arguments"><code>init_arg</code></a>も参照してください。</p>

<p>なお、『<a href="http://www.oreilly.co.jp/books/4873113008/">Perlベストプラクティス</a>』風に<code>reader =&gt; 'get_foo', writer =&gt; 'set_foo'</code>のように指定するには<a href="http://search.cpan.org/perldoc?MooseX::FollowPBP"><code>MooseX::FollowPBP</code></a>を使います。また、<code>reader =&gt; 'foo', writer =&gt; 'set_foo'</code>の指定は<a href="http://search.cpan.org/perldoc?MooseX::SemiAffordanceAccessor"><code>MooseX::SemiAffordanceAccessor</code></a>で代替可能です。</p>

<h4><span id="type_constraints_and_coercions">型制約と型変換/Type Constraints and Coercions</span></h4>

<pre><code>isa =&gt; $type_constraint
isa =&gt; "$some_type_constraint | $other_type_constraint"
</code></pre>

<p>指定した型制約にアトリビュートの値が適合していることを要求します。<code>does</code>とは排他指定です。</p>

<blockquote>
  <p>cf. <a href="#type_constraints">型制約/Type Constraints</a></p>
</blockquote>

<pre><code>does =&gt; $role_name
</code></pre>

<p>アトリビュートの値であるオブジェクトのクラスが<code>$role_name</code>のロールを消費していることを要求します。<code>isa</code>とは排他指定です。</p>

<blockquote>
  <p>cf. <a href="#consuming_roles"><code>with</code></a>, <a href="#roles">ロール/Roles</a></p>
</blockquote>

<pre><code>coerce =&gt; $bool
</code></pre>

<p>真の場合、<code>isa</code>で指定した型制約にアトリビュートの値が適合しない時に型変換を試みます。<code>weak_ref</code>と排他指定です。</p>

<blockquote>
  <p>cf. <a href="#type_coercions">型変換/Type Coercions</a></p>
</blockquote>

<pre><code>weak_ref =&gt; $bool
</code></pre>

<p>真の場合、アトリビュートの値（リファレンス）を「弱いリファレンス<span class="en">/weak reference</span>」にします。<code>coerce</code>と排他指定です。</p>

<p>これは循環参照<span class="en">/circular refearence</span>を防止する用途に使われます。</p>

<pre><code>auto_deref =&gt; $bool
</code></pre>

<p>真の場合、読み取りメソッドの戻り値を自動的にデリファレンス<span class="en">/dereference</span>します。<code>isa</code>の指定が必須です。</p>

<p><a href="#delegation_to_common_perl_data_structures">Perlデータ構造体への委譲</a>を行う方が手堅いです。</p>

<h4><span id="constructor_arguments">コンストラクター引数/Constructor Arguments</span></h4>

<pre><code>init_arg =&gt; $argument_key
init_arg =&gt; undef
</code></pre>

<p>コンストラクター<code>new</code>の引数（正確には<a href="#hooks_into_constructor"><code>BUILDARGS</code></a>メソッドの戻り値）のハッシュキー名を明示的に指定します。</p>

<p>オプション無指定時には$attribute_nameと同じキー名を取ります。<code>undef</code>を指定すると、コンストラクター引数を取りません。</p>

<pre><code>required =&gt; $bool
</code></pre>

<p>アトリビュートに値が設定されていることを要求します。</p>

<p>コンストラクター<code>new</code>の引数（正確には<a href="#hooks_into_constructor"><code>BUILDARGS</code></a>メソッドの戻り値）のハッシュに<code>init_arg</code>で指定されたキー（<code>init_arg</code>が未指定ならアトリビュートと同名のキー）が存在していなければ、実行時に例外が送出され、インスタンスを生成できません。</p>

<blockquote>
  <p>cf. <a href="#hooks_into_constructor">コンストラクターのフック</a></p>
</blockquote>

<p><a href="#lazy_building_predication_and_cleaning"><code>lazy</code>や<code>lazy_build</code></a>と一緒に指定すると、例外は送出されませんが意図した動作となりません。遅延設定の方が優先され、<code>new</code>に引数を渡さない場合でも例外が送出されません。</p>

<p>なお、ロールのシュガー関数<a href="#interfaces"><code>requires</code></a>と混同しないように気を付けてください。</p>

<h4><span id="lazy_building_predication_and_cleaning">値の遅延設定と設定状況/Lazy Building, Predication and Cleaning</span></h4>

<pre><code>lazy =&gt; $bool
</code></pre>

<p>真の場合、アトリビュートを遅延設定します。</p>

<p>コンストラクター<code>new</code>の引数へ（正確には<a href="#hooks_into_constructor"><code>BUILDARGS</code></a>メソッドの戻り値で）当該アトリビュートを指定せずにインスタンスを生成した場合、遅延設定されたアトリビュートの値は未設定状態となっています。また、一度設定されたアトリビュートの値を消去用メソッド<span class="en">/clearer methods</span>で消去した場合も未設定状態となります。</p>

<p>こうしたアトリビュートの値が未設定状態の場合、次にそのアトリビュートにアクセスされた時点でデフォルト値が設定されます。</p>

<p>遅延設定する場合、アクセス時に遅延設定されるデフォルト値として、<a href="#default_values"><code>default</code>または<code>builder</code></a>の指定が必須です。</p>

<pre><code>lazy_build =&gt; $bool
</code></pre>

<p>真の場合、<code>lazy =&gt; 1, predicate =&gt; "has_$attribute_name", clearer =&gt; "clear_$attribute_name", builder =&gt; "_build_$attribute_name"</code>と同じ指定になります。</p>

<pre><code>predicate =&gt; $predicater_method_name
</code></pre>

<p>アトリビュートに値が設定されていれば真を返す断定用メソッド<span class="en">/predicator method</span>を、指定したメソッド名でクラスへ生成します。</p>

<p>なお、<code>undef</code>という値が設定されていても、真が返ります。値が設定されていない状態と、値に未定義値<code>undef</code>が設定されている状態は異なるからです。伝統的なハッシュベースのPerl5クラスでは、<code>if exists $self-&gt;{foo}</code>に相当します。</p>

<pre><code>clearer =&gt; $clearer_method_name
</code></pre>

<p>アトリビュートの値を未設定状態にする消去用メソッド<span class="en">/clearer method</span>を、指定したメソッド名でクラスへ生成します。</p>

<p><a href="#triggers"><code>trigger</code></a>と組み合わせると、アトリビュートが絡み合うクラスを簡潔に実装できます。</p>

<blockquote>
  <p>cf. <a href="http://blog.eorzea.asia/2009/10/post_72.html">Mooseのtriggerの効果的な使い方 ～ lazyとclearerとの併用</a></p>
</blockquote>

<h4><span id="default_values">デフォルト値/Default Values</span></h4>

<pre><code>default =&gt; $default_value
default =&gt; sub { my ($self) = @_; ... }
</code></pre>

<p>遅延設定時のデフォルト値を指定します。</p>

<p>デフォルト値をリファレンスにしたい場合、<code>sub { [ ... ] }</code>などのようにコードリファレンス内で指定します。直接指定するとコンパイル時に例外が送出されます。</p>

<p>全インスタンスで参照先の値（リファレント）を共有させたい場合、<code>my @foo = (); ... has bar =&gt; ( is =&gt; 'ro', default =&gt; sub { \@foo } );</code>や<code>my $foo = []; .... has bar =&gt; ( is =&gt; 'ro', default =&gt; sub { $foo } )</code>のように、コードリファレンスの外で生成した値をコードリファレンス内で使ってください。</p>

<pre><code>builder =&gt; $builder_method_name
</code></pre>

<p>デフォルト値を返すビルダーメソッド<span class="en">/builder methods</span>のメソッド名を指定します。</p>

<p><code>default =&gt; \&amp;builder_method_name</code>の指定とほぼ同様です。</p>

<p>ロールやサブクラスでビルダーメソッドを実装したり上書きしたりできるので、<code>default</code>よりも好ましい指定です。</p>

<p><code>builder</code>を直接または<code>lazy_build</code>経由で指定した場合、当該クラス, クラス継承ツリー, 消費ロール群のいずれにもビルダーメソッドが存在しないと、デフォルト値を設定するタイミングで例外が送出されます（コンパイル時ではありません）。</p>

<h4><span id="triggers">トリガー/Triggers</span></h4>

<pre><code>trigger =&gt; sub { my ($self, $new_value) = @_; ... }
</code></pre>

<p>アトリビュートに値が設定された後に実行するコードリファレンスです。</p>

<p>書き込みメソッド実行後の他、コンストラクター<code>new</code>の引数で値を指定した場合にも動作します。ただし、デフォルト値が設定された場合には動作しません。</p>

<h4><span id="delegation_setting">委譲設定/Delegation Setting</span></h4>

<pre><code>handles =&gt; [ @delegated_method_names ]
handles =&gt; { $delegating_method_name =&gt; $delegated_method_name }
handles =&gt; { $curried_method_name =&gt; [ $delegated_method_name, @args ] }
handles =&gt; qr{ $pattern_of_delegated_method_names }
handles =&gt; $role_name
handles =&gt; sub { ... }
</code></pre>

<p>アトリビュートの値（オブジェクトなど）に対する委譲メソッドを、クラスへ設定します。</p>

<p><code>isa</code>の指定が必須です。</p>

<blockquote>
  <p>cf. <a href="#delegation">委譲/Delegation</a></p>
</blockquote>

<h4><span id="documentation">文書化/Documentation</span></h4>

<pre><code>documentation =&gt; $documentation_string
</code></pre>

<p>アトリビュートを説明する文書を指定します。<code>has 'ssn' =&gt; (is =&gt; 'ro', documentation =&gt; 'Social Security Number');</code>など。</p>

<h3><span id="types">型/Types</span></h3>

<h4><span id="type_constraints">型制約/Type Constraints</span></h4>

<pre><code>package Foo;
use Moose;
has bar =&gt; ( is =&gt; 'rw', isa =&gt; 'Int' );

package main;
use Foo;
my $foo = Foo-&gt;new(bar =&gt; 42);
$foo-&gt;bar('baz');               # 'baz'は文字列（整数以外）なので例外を送出
</code></pre>

<p><a href="#type_constraints_and_coercions"><code>isa</code></a>で型制約を指定します。ただし、<code>Moose</code>の型制約はPerl6にあるような「本物の」型ではありません。コンパイル時ではなく実行時に（アトリビュートに値が設定された時点で）型チェックされます。</p>

<h4><span id="build_in_type_constraints">組み込みの型制約/Build-in Type Constraints</span></h4>

<pre><code>Any : 制約なし
Maybe[TypeName] : UndefかTypeName
Item : 制約なし
    Bool : 真偽値
    Undef : 未定義（取扱注意）
    Defined : 真値
        Value : プリミティブ値
            Num : 数値（'NaN', 'Inf', '0 but true'などはStr型）
                Int : 整数
            Str : 文字列
                RoleName : ロード済みのロール名（Moose 0.84+では非推奨）
                ClassName : ロード済みのクラス名
        Ref : リファレンス
            ScalarRef : スカラーリファレンス
            ArrayRef or ArrayRef[TypeName] : 配列リファレンス
            HashRef or HashRef[TypeName] : ハッシュリファレンス
            CodeRef : コードリファレンス
            RegexpRef : 正規表現リファレンス
            GlobRef : グロブリファレンス
                FileHandle : ファイルハンドル
            Object : オブジェクト
                Role : ロール
</code></pre>

<p><code>Moose</code>組み込みの型制約は型階層<span class="en">/type hierarchy</span>をなしています。例えば<code>Str</code>型制約を満たす文字列値<code>'foo'</code>は<code>Value</code>型制約も満たします。</p>

<h4><span id="parameterized_types">パラメーター化された型/Parameterized Types</span></h4>

<p>上記の<code>[TypeName]</code>は、データの中身などについて型を<code>TypeName</code>に制約する指定です。ドキュメントには<code>[`a]</code>などと記載されています。例えば<code>ArrayRef[Int]</code>は「全要素の値が<code>Int</code>型制約を満たす配列」という制約を意味します。</p>

<h4><span id="automatically_created_types">自動生成された型/Automatically Created Types</span></h4>

<pre><code>isa =&gt; 'DateTime'
</code></pre>

<p>未知の文字列はクラス名とみなされて型が自動生成されます。</p>

<h4><span id="type_unions">型結合/Type Unions</span></h4>

<pre><code>isa =&gt; 'Str | ArrayRef'
</code></pre>

<p>「<code>Str</code>または<code>ArrayRef</code>」の制約を意味します。</p>

<p>ただし、独自の型を新設して<a href="#type_coercions">型変換</a><span class="en">/coerce</span>する方が手堅いです。例えばクラス内部で<code>Str</code>と<code>ArrayRef</code>に異なった処理を実装するよりも、アトリビュートに値を入れる時点で<code>Str</code>を1要素だけ持つ<code>ArrayRef</code>にまとめてしまった方が簡潔です。</p>

<h4><span id="to_define_your_own_types">独自の型の定義/To Define Your Own Types</span></h4>

<pre><code>use Moose::Util::TypeConstraints;
</code></pre>

<p>型制約や型変換用のシュガー関数をインポートします。</p>

<pre><code>type $type_name
    =&gt; where { ... }
    =&gt; message { ... };
</code></pre>

<p>独自の型制約を新設します。</p>

<p><code>where</code>ブロックでは、アトリビュートに与えられた値<code>$_</code>を使って、それが型制約に合致するか否かを示す真偽値を返します。</p>

<p><code>message</code>ブロックの記述は任意です。<code>where</code>が偽であった場合の<code>confess</code>用エラーメッセージを文字列で返せます。<code>$_</code>も使えます。</p>

<pre><code>subtype $sub_type_name
    =&gt; as $parent_type_name
    =&gt; where { ... }
    =&gt; message { ... };
</code></pre>

<p>既存の型のサブタイプ<span class="en">/subtypes</span>を新設します。</p>

<p><code>as</code>で親のタイプ（スーパータイプ）を指定します。新設したサブタイプは、親のタイプの制約と、<code>where</code>ブロック内の制約を共に満たす必要があります。</p>

<p><code>where</code>ブロックを記述しない場合、親のタイプと全く同じ制約が適用されます。</p>

<pre><code>enum $enum_name =&gt; @values;
</code></pre>

<p>列挙型<span class="en">/enumerated type</span>の指定です。</p>

<pre><code>subtype $sub_type_name
    =&gt; as class_type 'SomeClassName';
</code></pre>

<p>クラス用の型を明示的にサブタイプ化する指定です。</p>

<p><a href="#automatically_created_types">型の自動生成</a>は、実際にはこの構文と同じ動作をします。</p>

<pre><code>type 'My::App::Types::Foo'
    ...
</code></pre>

<p>型はグローバルな名前空間に登録されるので、自分の型は自分用の名前空間に所属させることが推奨されています。</p>

<p>なお、<a href="http://search.cpan.org/search?query=MooseX::Types::&amp;mode=module"><code>MooseX::Types::*</code></a>名前空間には、様々な型制約・型変換モジュールが登録されています。</p>

<h4><span id="type_coercions">型変換/Type Coercions</span></h4>

<pre><code>coerce $type_name
    =&gt; from $some_type_name
        =&gt; via { ... }
    =&gt; from $other_type_name
        =&gt; via { ... };
</code></pre>

<p><code>$some_type_name</code>などの型に合致する場合に、<code>via</code>ブロック内で<code>$type_name</code>への型変換を試みる指定です。<code>via</code>ブロックではアトリビュートに与えられた値<code>$_</code>を変換して、型制約に合致する値を返します。</p>

<p>型を適用するアトリビュートを<code>has</code>する際に<code>coerce =&gt; 1</code>することも忘れずに。</p>

<pre><code>subtype 'My::App::StrOrHashToArray'
    =&gt; as 'ArrayRef';
corece 'My::App::StrOrHashToArray'
    =&gt; from 'Str'
        =&gt; via { [$_] }
    =&gt; from 'Hash'
        =&gt; via { [%$_] };
</code></pre>

<p><code>Str</code>や<code>Hash</code>から<code>ArrayRef</code>に変換する例です。</p>

<p>型はグローバルな名前空間に登録されるので、組み込みの型や自動生成される型はそのまま<code>coerce</code>せず、必ず<code>subtype</code>化してから<code>coerce</code>しましょう。</p>

<h4><span id="moosex_types"><code>MooseX::Types</code></span></h4>

<!--

冗長なので記述例は省略しました。



7b367975bab7f412a6a2609e22e79f43



-->

<p><a href="http://search.cpan.org/perldoc?MooseX::Types"><code>MooseX::Types</code></a>を使うと、名前空間を自動で掘ったり、型を裸のワード<span class="en">/raw words</span>で呼べたりできます。</p>

<p><code>MooseX::Types</code>のAPIは<code>Moose::Util::TypeConstraints</code>とほぼ同様ですが、裸のワードを使う都合上、（左辺値を暗黙的にクォートする）ファットカンマ(<code>=&gt;</code>)ではなく、シンカンマ(<code>,</code>)を使うことになります。</p>

<h3><span id="delegation">委譲/Delegation</span></h3>

<p>委譲は<a href="#delegation_setting"><code>handles</code></a>で設定します。</p>

<h4><span id="delegation_to_an_object">オブジェクトへの委譲/Delegation to an Object</span></h4>

<pre><code>has datetime =&gt; (
    is      =&gt; 'rw',
    isa     =&gt; 'DateTime',
    handles =&gt; [qw(ymd hms)],
);
</code></pre>

<p><a href="http://search.cpan.org/perldoc?DateTime"><code>DateTime</code></a>インスタンスのメソッドへの委譲を行う例。<code>$my_instance-&gt;ymd</code>で、<code>$my_instance-&gt;datetime-&gt;ymd</code>と同じ処理を実現できます。</p>

<pre><code>has datetime =&gt; (
    is      =&gt; 'rw',
    isa     =&gt; 'DateTime',
    handles =&gt; {
        yyyymmdd =&gt; 'ymd',
        hhmmss   =&gt; 'hms',
    },
);
</code></pre>

<p><code>handles</code>にハッシュリファレンスを指定した場合、<code>クラスに生やすメソッド =&gt; 委譲先のメソッド</code>という構文となります。<code>$my_instance-&gt;yyyymmdd</code>で、<code>$my_instance-&gt;datetime-&gt;ymd</code>と同じ処理を実現できます。</p>

<h4><span id="method_currying">メソッドのカリー化/Method Currying</span></h4>

<pre><code>has datetime =&gt; (
    is      =&gt; 'rw',
    isa     =&gt; 'DateTime',
    handles =&gt; {
        yyyymmdd =&gt; [ 'ymd' =&gt; ( ''  ) ],
        hhmmss   =&gt; [ 'hms' =&gt; ( '_' ) ],
    },
);
</code></pre>

<p>委譲先のメソッドを<a href="http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96">カリー化</a><span class="en">/currying</span>できます（<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.89_01"><code>Moose 0.89_01</code></a>以降, <a href="http://cpansearch.perl.org/dist/Mouse/Changes"><code>Mouse 0.50_02</code></a>以降）。</p>

<p>上記の例では、<code>$my_instance-&gt;yyyymmdd</code>で<code>$my_instance-&gt;datetime-&gt;ymd('')</code>と同じ処理を実現でき、デリミターなしの<code>YYYYMMDD</code>形式の文字列を得られます。また、<code>$my_instance-&gt;hhmmss</code>で<code>$my_instance-&gt;datetime-&gt;hms('_')</code>と同じ処理を実現できます。</p>

<h4><span id="delegation_to_common_perl_data_structures">Perlの通常データ構造体への委譲/Delegation to Common Perl Data Structures</span></h4>

<p><a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.89_01"><code>Moose 0.89_01</code></a>以降には、ネイティブトレート<span class="en">/native traits</span>が組み込まれています。</p>

<pre><code>has friends =&gt; (
    traits  =&gt; [qw(Array)],
    is      =&gt; 'rw',
    isa     =&gt; 'ArrayRef',
    handles =&gt; {
        all_friends  =&gt; 'elements',
        sort_friends =&gt; 'sort_in_place',
    },
);
</code></pre>

<p>配列用ネイティブトレート<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Array"><code>Array</code></a>を使った委譲の例。（オブジェクトではない）単なる配列リファレンスに対するヘルパーメソッドを生成しています。この場合、<code>$my_instance-&gt;all_friends</code>で<code>@{ $my_instance-&gt;friends }</code>と同じ処理を実現できます。これは<code>auto_deref =&gt; 1</code>として<code>$my_instance-&gt;friends</code>で配列を得るよりも手堅い手法です。</p>

<p>この他にも、よく使う関数をヘルパーメソッドとして使えます。</p>

<pre><code>$my_instance-&gt;friends( [ sort @{ $my_instance-&gt;friends } ] );
</code></pre>

<p>例えば上記の処理は</p>

<ol>
<li>配列リファレンスとしての値をアトリビュートから得て</li>
<li>デリファレンスして</li>
<li>リファレントである配列を<code>sort</code>して</li>
<li>その配列をリファレンスとしてアトリビュートの値に戻す</li>
</ol>

<p>という手間を掛けていますが、これを</p>

<pre><code>$my_instance-&gt;sort_friends;
</code></pre>

<p>だけで済ませられます。つまり、内部実装（<code>friends</code>が配列リファレンスであること）を隠蔽できて、クラスを使用する側も余計なことを考えなくて済むようになります。</p>

<h5><code>MooseX::AttributeHelpers</code></h5>

<p>この機能の取込元である<a href="http://search.cpan.org/perldoc?MooseX::AttributeHelprs"><code>MooseX::AttributeHelpers</code></a>でもほぼ同様の機能を実現できますが、<code>Moose</code>本体への取込に伴い、現在は非推奨<span class="en">/deprecated</span>となっています。</p>

<p><a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Array"><code>Array</code></a>ネイティブトレートは、<code>MooseX::AttributeHelpers</code>の<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Custom::Collection::Array"><code>Collection::Array</code></a>メタクラスに相当します。</p>

<p>また、<code>Mouse</code>は<code>0.50_01</code>時点では<code>Moose</code>相当のネイティブトレートが存在しないので、<a href="http://search.cpan.org/perldoc?MouseX::AttributeHelprs"><code>MouseX::AttributeHelpers</code></a>を使います。または、ネイティブトレート相当の使用感がある<a href="http://search.cpan.org/perldoc?MouseX::NativeTraits"><code>MouseX::NativeTraits</code></a>を使います。</p>

<h4><span id="helper_methods_from_native_traits">ネイティブトレートによるヘルパーメソッド/Helper Methods from Native Traits</span></h4>

<h5>数値/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Number"><code>Number</code></a></h5>

<pre><code>set($new_number)                    # $number = $new_number
add($adding_number)                 # $number += $adding_number
sub($subtracting_number)            # $number -= $subtracting_number
mul($multiplying_number)            # $number *= $multiplying_number
div($deviding_number)               # $number /= $deviding_number
mod($deviding_number)               # $number %= $deviding_number
abs()                               # $number = abs $number
</code></pre>

<h5>カウンター/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Counter"><code>Counter</code></a></h5>

<pre><code>set($new_count)                     # $count = $new_count
inc()                               # $count ++
dec()                               # $count --
reset()                             # $count = $default_value
</code></pre>

<h5>文字列/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::String"><code>String</code></a></h5>

<pre><code>inc()                               # $string ++ (from 'a' to 'b', dec() is not available)
append($other_string)               # $string .= $other_string
prepend($other_string)              # $string = $other_string . $string
replace($pattern, $replacement)     # $string =~ s/$pattern/$replacement/ ($pattern accepts qr{}xmsi)
match($pattern)                     # $string =~ m/$pattern/ ($pattern accepts qr{}xmsi)
chop()                              # chop $string
chomp()                             # chomp $string
clear()                             # $string = q{}
length()                            # length $string
substr(@args)                       # substr $string, $offset, $length, $replacement
</code></pre>

<h5>真偽値/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Bool"><code>Bool</code></a></h5>

<pre><code>set()                               # $bool = 1
unset()                             # $bool = 0
toggle()                            # from 1 to 0, from 0 to 1
not()                               # not $bool
</code></pre>

<h5>ハッシュリファレンス/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Hash"><code>Hash</code></a></h5>

<pre><code>get(@keys)                          # $hashref-&gt;{$key}, @$hashref{@keys}
set(%keys_and_values)               # $hashref = { $key =&gt; $value, ... }
delete(@keys)                       # delete $hashref-&gt;{$key}, delete @$hashref{@keys}
keys()                              # keys %$hashref
exists($key)                        # exists $hashref-&gt;{$key}
defined($key)                       # defined $hashref-&gt;{$key}
values()                            # values %$hashref
kv()                                # key/value pairs as an array of array references
elements()                          # key/value pairs as a flattened list
clear()                             # %$hashref = ()
count()                             # scalar keys %$hashref
accessor($key)                      # get($key)
accessor($key, $value)              # set($key =&gt; $value)
</code></pre>

<h5>配列リファレンス/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Array"><code>Array</code></a></h5>

<pre><code>count()                             # scalar @$arrayref
is_empty()                          # if scalar @$arrayref
elements()                          # @$arrayref
get($index)                         # $arrayref-&gt;[$index]
pop()                               # pop @$arrayref
push(@values)                       # push @$arrayref, @values
shift()                             # shift @$arrayref
unshift(@values)                    # unshift @$arrayref, @values
splice($offset, $length, @values)   # splice @$arrayref, $offset, $length, @values
first(sub { ... })                  # List::Util::first { ... } @$arrayref
grep(sub { ... })                   # grep { ... } @$arrayref
map(sub { ... })                    # map { ... } @$arrayref
reduce(sub { ... })                 # List::Util::reduce { ... } @$arrayref (Moose 0.89_02+)
sort()                              # sort @$arrayref
sort(sub { $_[0] cmp $_[1] })       # sort { $a cmp $b } @$arrayref
sort_in_place()                     # @$arrayref = sort @$arrayref
sort_in_place(sub { ... })          # @$arrayref = sort { ... } @$arrayref
shuffle()                           # List::Util::shuffle @$arrayref (Moose 0.89_02+)
uniq()                              # List::MoreUtils::uniq @$arrayref (Moose 0.89_02+)
join($string)                       # join $string, @$arrayref
set($index, $value)                 # $arrayref-&gt;[$index] = $value
delete($index)                      # delete $arrayref-&gt;[$index]
insert($index, $value)              # splice @$arrayref, $index, 0, $value
clear()                             # @$arrayref = ()
accessor($index)                    # get($index)
accessor($index, $value)            # set($index, $value)
natatime($n, $code)                 # $i = List::MoreUtils::natatime $n, @$arrayref; while (@v = $i-&gt;()) { $code-&gt;(@v) } (Moose 0.89_02+)
</code></pre>

<h5>コードリファレンス/<a href="http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native::Trait::Code"><code>Code</code></a></h5>

<p><a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#0.90"><code>Moose 0.90</code></a>以降の機能です。</p>

<pre><code>execute(@args)                      # &amp;$coderef(@args)
execute_method(@args)               # $invocant-&gt;$coderef(@args)
</code></pre>

<h3><span id="construction_and_destruction_of_instances">インスタンスの生成と破棄/Construction and Destruction of Instances</span></h3>

<p><code>Moose</code>に基づくクラスのインスタンスは<code>My::Class-&gt;new;</code>で生成します。</p>

<p>Perl5の素のオブジェクト指向で作ったインスタンスと同様、インスタンスの破棄は参照カウント<span class="en">/reference count</span>が<code>0</code>になった時に行われます。</p>

<h4><span id="hooks_into_constructor">コンストラクターのフック/Hooks into Constructor</span></h4>

<pre><code>sub BUILDARGS { my ($class, @init_args) = @_; ... }
</code></pre>

<p><code>Moose</code>クラスや<code>Moose</code>ロールでは、コンストラクターであるクラスメソッド<code>new</code>を上書きしてはなりません。ただし、<code>BUILDARGS</code>クラスメソッドをフックすることで、<code>new</code>へ渡る引数を編集することができます。</p>

<p>ハッシュかハッシュリファレンスを要求する<code>new</code>に対して、配列やスカラー値なども受け容れるようにしたり、引数を編集したりするために使えます。</p>

<pre><code>sub BUILDARGS {
    my ($class, @init_args) = @_;

    if (@init_args == 0 &amp;&amp; ! ref $init_args[0]) {
        return { foo =&gt; $init_args[0] };
    }
    else {
        return $class-&gt;SUPER::BUILDARGS(@init_args);
    }
}
</code></pre>

<p><code>BUILDARGS</code>ではフォールバックとしてスーパークラスの<code>BUILDARGS</code>を呼ぶことが推奨されています（<code>Moose</code>に基づくクラスは内部的には<a href="http://search.cpan.org/perldoc?Moose::Object"><code>Moose::Object</code></a>を継承しているので、何も<a href="#class_inheritance"><code>extends</code></a>していないクラスでも<code>SUPER</code>があります）。</p>

<pre><code>around BUILDARGS =&gt; sub {
    my ($next, $class, @init_args) = @_;

    if (@init_args == 0 &amp;&amp; ! ref $init_args[0]) {
        return { foo =&gt; $init_args[0] };
    }
    else {
        return $class-&gt;$next(@init_args);
    }
};
</code></pre>

<p>サブクラスやロールでさらに細かい処理をする場合もあるので、<code>BUILDARGS</code>を<code>around</code>メソッドモディファイヤーで修飾すると便利です。</p>

<pre><code>sub BUILD { my ($self, @init_args) = @_; ... }
</code></pre>

<p>インスタンス生成後の後処理を実装します。<code>$self-&gt;SUPER::BUILD</code>を呼んではいけません。</p>

<p>この時点では既にインスタンスは生成されています。従って、<a href="#type_constraints_and_coercions"><code>isa</code></a>や<a href="#constructor_arguments"><code>required</code></a>などへの対策は<code>BUILDARGS</code>で実装する必要があります。</p>

<p><code>BUILD</code>の戻り値は無視されます（<code>new</code>の戻り値は<code>$self</code>となります）。</p>

<h4><span id="hooks_into_destructor">デストラクターのフック/Hooks into Destructor</span></h4>

<pre><code>sub DEMOLISH { my ($self, $arg) = @_; ... }
</code></pre>

<p><code>Moose</code>クラスや<code>Moose</code>ロールでは、デストラクターであるメソッド<code>DESTROY</code>を上書きしてはなりません。代わりに<code>DEMOLISH</code>クラスメソッドをフックすることで、デストラクターの起動のタイミングで任意の処理を実行することができます。</p>

<p><code>$self-&gt;SUPER::DEMOLISH</code>を呼んではいけません。</p>

<h3><span id="other_tidbits">その他の内容の触り/Other Tidbits</span></h3>

<h4><span id="measures_against_namespace_pollution">名前空間の汚染への対策/Measures against Namespace Pollution</span></h4>

<p><code>Moose</code>関連シュガー関数は、<code>use Moose</code>したパッケージの名前空間を汚染します。つまり、そのままでは外部から<code>My::Class-&gt;has</code>などで呼ばれてしまいます。</p>

<pre><code>no Moose;
</code></pre>

<p><code>use Moose</code>した後、シュガー関数を使い終わったら、<code>Moose</code>関連シュガー関数をアンインポートします。</p>

<p><code>Moose::Role</code>や<code>Moose::Util::TypeConstraints</code>を<code>use</code>した場合は、それらも同様に<code>no</code>してください。</p>

<pre><code>use namespace::autoclean;
</code></pre>

<p><a href="http://search.cpan.org/perldoc?namespace::autoclean"><code>namespace::autoclean</code></a>モジュールで名前空間を掃除することも可能です。</p>

<pre><code>use namespace::clean -except =&gt; [qw(meta)];
</code></pre>

<p>上記の<a href="http://search.cpan.org/perldoc?namespace::clean"><code>namespace::clean</code></a>による代替です。<code>use Moose</code>した後に<code>use namespace::clean</code>することと、（<code>use Moose</code>の場合は）<code>meta</code>を掃除対象外にとすることに留意してください。</p>

<h4><span id="meta_object_protocol_and_class_mop">メタオブジェクトプロトコルと<code>Class::MOP</code>/Meta Object Protocol and <code>Class::MOP</code></span></h4>

<p><code>Moose</code>はMOP(メタオブジェクトプロトコル<span class="en">/Meta Object Protocol</span>)に基づくオブジェクト指向プログラミング機構を提供する<a href="http://search.cpan.org/perldoc?Class::MOP"><code>Class::MOP</code></a>のラッパーです。</p>

<p>例えば、シュガー関数は<code>Class::MOP</code>の各種メソッドを簡潔にしたものです。</p>

<h5><span id="metaclasses">メタクラス/Metaclasses</span></h5>

<p><code>use Moose;</code>すると、当該パッケージに紐付くメタクラス<span class="en">/metaclasses</span>オブジェクトが生成され、かつ、<a href="http://http://search.cpan.org/perldoc?Moose::Object"><code>Moose::Object</code></a>が自動的に継承されます。</p>

<p>「クラスにはアトリビュートがある」や「クラスへメソッドを生やす」などと書いてきましたが、実際にはこのメタクラスオブジェクトに対して内部的な操作を行っています。</p>

<p>これらは<a href="http://moose.perl.org/"><code>Moose</code>ホームページ</a>の<a href="http://moose.perl.org/images/class_mop_model.jpg"><code>Class::MOP</code> object model diagram</a>で図解されています。</p>

<p>この関係はRubyのクラスが実際にはクラスオブジェクトであることと似ています。</p>

<h5><span id="introspection">イントロスペクション/Introspection</span></h5>

<pre><code>my $meta = __PACKAGE__-&gt;meta;
</code></pre>

<p>パッケージに紐付くメタクラスを取得します。</p>

<p>アトリビュートやメソッドや消費ロールなど、<a href="http://search.cpan.org/search?query=Moose::Meta::&amp;mode=module"><code>Moose::Meta::*</code></a>にあるような様々な情報を実行時に参照および編集できます。</p>

<h4><span id="speed_up_by_immutabilizing_metaclasses">メタクラスの不変化による高速化/Speed Up by Immutabilizing Metaclasses</span></h4>

<pre><code>__PACKAGE__-&gt;meta-&gt;make_immutable;
</code></pre>

<p>パッケージに紐付くメタクラスを不変化します（実行時のメタ情報の編集を禁止します）。これにより、コンストラクターの処理が高速になります。</p>

<p><code>has</code>などでメタクラスを編集した後に記述します。戻り値が<code>1</code>なので、パッケージ末尾の<code>1;</code>を兼ねて記述することも可能です。特別なことをしない限り、常に<code>make_immutable</code>するとよいでしょう。</p>

<p><code>make_immutable</code>した後に動的にメタ情報を編集したい場合には、<code>__PACKAGE__-&gt;meta-&gt;make_mutable</code>で可変化します。</p>

<h4><span id="mouse"><code>Mouse</code></span></h4>

<p><a href="http://search.cpan.org/perldoc?Mouse"><code>Mouse</code></a>は<code>Moose</code>とほぼ同様のAPIを持つ高速版モジュールです。MOPの奥深い処理を除いて、幅広い互換性を持っています。</p>

<p><code>Mouse</code>は<del datetime="2010-02-21T08:54:35+09:00"><code>Class::MOP</code>関連の処理を省いていたり、XSで実装されている部分が多かったりするので、</del><ins datetime="2010-02-21T08:54:35+09:00">効率的な実装がなされているため</ins>、<code>Mouse</code>のロード, インスタンスの生成, <code>Mouse</code>クラスに於ける処理の実行時のいずれも<code>Moose</code>より高速に動作します。</p>

<pre><code>package My::Class;
use Mouse;
</code></pre>

<p>パッケージを<code>Mouse</code>に基づいたクラスにします。</p>

<pre><code>package My::Role;
use Mouse::Role;
</code></pre>

<p>パッケージを<code>Mouse::Role</code>に基づいたロールにします。</p>

<pre><code>package My::Class;
use Any::Moose;

package My::Role;
use Any::Moose '::Role';
</code></pre>

<p>既に<code>Moose</code>をロード済みであればそちらを使うように、または将来的に<code>Moose</code>がさらに高速化した場合に<code>Moose</code>に切り替えられるように、<a href="http://search.cpan.org/perldoc?Any::Moose"><code>Any::Moose</code></a>モジュールを利用すると手堅いです。</p>

<p>なお、『<a href="http://www.amazon.co.jp/dp/4798119172">モダンPerl入門</a>』で言及されている<a href="http://search.cpan.org/perldoc?Squirrel"><code>Squirrel</code></a>は、現在では非推奨<span class="en">/deprecated</span>となっています。</p>

<h4><span id="moosex_expansion_modules"><code>MooseX</code>拡張モジュール/<code>MooseX</code> Expansion Modules</span></h4>

<p><code>Moose</code>の拡張モジュールは<a href="http://search.cpan.org/search?query=MooseX::&amp;mode=module"><code>MooseX::*</code></a>名前空間にあります。<code>Mouse</code>版の名前空間は<a href="http://search.cpan.org/search?query=MooseX::&amp;mode=module"><code>MouseX::*</code></a>です。</p>

<p><a href="http://search.cpan.org/perldoc?Moose::Manual::MooseX"><code>Moose::Manual::MooseX</code></a>では、お勧めのモジュールがいくつか紹介されています。</p>

<h4><span id="oose"><code>oose</code></span></h4>

<pre><code>perl -Moose=Foo -e 'has bar =&gt; (is =&gt; q(ro), default =&gt; q(baz)); print Foo-&gt;new-&gt;bar'
</code></pre>

<p><a href="http://search.cpan.org/perldoc?oose"><code>oose</code></a>はワンライナー<span class="en">/one liner</span>に於いて<code>Moose</code>のシュガー関数を使えるようにするモジュールです。<code>Mouse</code>にも<a href="http://search.cpan.org/perldoc?ouse"><code>ouse</code></a>があります。</p>

<h4><span id="timing_to_consuming_interfaces">インターフェースの消費タイミング/Timing to Consuming Interfaces</span></h4>

<!--

冗長なので記述例は省略しました。



c801722fbfb48c0d4d77279fd163790a



`with`でロールを消費した時点で`@methods`を呼び出せる状態になっていなければ、コンパイル時に例外が送出されます。

-->

<!--

冗長なので記述例は省略しました。



67d870cf8d518dbc02b64624b04d2841



-->

<p><code>@methods</code>が消費元のクラスに実装されていなくても、消費元のクラスのスーパークラスや、消費元クラスが当該ロールを消費する前に既に消費している別のロールなどに実装されていれば、当該ロールを<code>with</code>した時点で<code>@methods</code>を呼び出せるため、問題ありません（インターフェースのロールとメソッドを実装してあるロールを一緒に<code>with</code>することも可能です）。</p>

<pre><code>package My::Interface;
use Moose::Role;
requires qw(foo);

package My::Class;
use Moose;
# with qw(My::Interface);   # ここでwithするとエラー
has foo =&gt; (
    is =&gt; 'ro',
);
with qw(My::Interface);     # ここでwithする必要がある
</code></pre>

<p>アトリビュートへのアクセッサーメソッドを<code>requires</code>する際には注意が必要です。<code>requires</code>を記述したロールを<code>with</code>で消費する前に（コードの前方で）、アトリビュートがクラス上に存在していなければなりません。</p>

<pre><code>package My::WithFoo;
use Moose::Role;
has foo =&gt; (
    is =&gt; 'ro',
);

package My::Class;
use Moose;
# with qw(My::Interface My::WithFoo);   # 同時に消費すると例外
with qw(My::WithFoo);                   # 先にfooを使えるようにしてから......
with qw(My::Interface);                 # インターフェースを適用する
</code></pre>

<p>アトリビュートを別のロールに実装している場合も同様です。</p>

<h4><span id="measures_against_method_conflict">メソッド衝突対策/Measures against Method Conflict</span></h4>

<!--

冗長なので記述例は省略しました。



14305ad25f88ce932b13cd4dac99ca7c



-->

<p>ロールとロール消費元のクラスで同名のメソッドが実装されている場合、クラス側に実装されているメソッドが優先され、ロール側で実装されているメソッドは呼ばれません。</p>

<!--

冗長なので記述例は省略しました。



0e9e72c6ab645777437b0a36cb94b6d6



-->

<p>クラスが消費している複数のロールに同名のメソッドが実装されている場合、メソッドが衝突<span class="en">/conflict</span>するのでコンパイル時に例外が送出されます。</p>

<pre><code>with (
    $some_role =&gt; {
        -alias    =&gt; { $method_name =&gt; $some_method_name },
        -excludes =&gt; { $some_method },
    },
);
</code></pre>

<p>この場合、<code>with</code>のオプションで元のメソッドを排除<span class="en">/exclusion</span>して別名化<span class="en">/aliasing</span>する必要があります。ただし、ロールのAPIを崩しているので、どうしても必要な場合を除いては避けた方がよいでしょう。</p>

<h4><span id="measures_against_testing">テスト対策/Measures against Testing</span></h4>

<p><a href="http://search.cpan.org/perldoc?Test::Perl::Critic"><code>Test::Perl::Critic</code></a>では、依存する<a href="http://search.cpan.org/perldoc?Perl::Critic"><code>Perl::Critic</code></a>のバージョン<code>1.094</code>以降、<code>strict</code>などのプラグマを有効化する<code>Moose</code>などのモジュールに対応していますので、<code>use Moose;</code>や<code>use Moose::Role;</code>があれば<code>use strict;</code>がないというチェックには引っ掛かりません。</p>

<p>ただし、それ以外に注意しておく点がいくつかあります。</p>

<ul>
<li><a href="http://blog.eorzea.asia/2009/08/post_46.html">Arkアプリケーションの開発者テストでTest::Perl::Criticを使う</a> : <code>Moose</code>などでないモジュールを<code>use</code>したモジュールに対する<code>use strict</code>存否チェックを回避するための<code>Perl::Critic</code>の設定に言及しています。</li>
<li><a href="http://blog.eorzea.asia/2009/12/post_83.html">Moose/Mouse用フックメソッドをPod::Coverageの対象から外す方法</a> : 題名の内容の他、Kwaliteeスコアラー<a href="http://search.cpan.org/perldoc?Module::CPANTS::Analyse"><code>Module::CPANTS::Analyse</code></a>によるチェックが回避不能と思われると言及しています。</li>
</ul>

<h4><span id="to_moose_or_not_to_moose"><code>Mooseを使うか否か</code>/To <code>Moose</code> or not to <code>Moose</code></span></h4>

<p><code>Moose</code>はPerl5に於いてポストモダンなオブジェクト指向プログラミングを行えるフレームワークです。もう「Perl5のオブジェクト指向は後付けだから汚い」などとはdisられません。</p>

<p><code>Moose</code>を使ったクラスは伝統的な手作りのクラスや<a href="http://search.cpan.org/perldoc?Class::Accessor::Fast"><code>Class::Accessor::Fast</code></a>などを利用したクラスなどに比べて以下のような利点があり、人気を博しています。</p>

<ul>
<li>DSL（<a href="http://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%9B%BA%E6%9C%89%E8%A8%80%E8%AA%9E">ドメイン固有言語</a><span class="en">/Domain Specific Language</span>）によって宣言的<span class="en">/declative</span>にクラスを記述できる</li>
<li>従来より遙かに少ない労力で格段に強力なオブジェクト指向プログラミングを行える（<code>Moose</code>のイディオムを伝統的なPerl5で書くとどうなるかが、<a href="http://search.cpan.org/perldoc?Moose::Manual::Unsweetened"><code>Moose::Manual::Unsweetened</code></a>や、ichikawayさんによるperl-mogers.orgの<a href="http://perl-mongers.org/2008/05/moose.html">Mooseに入門してみたよ</a>の記事などで言及されています）</li>
<li>APIに着目した<a href="http://ja.wikipedia.org/wiki/%E5%A5%91%E7%B4%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0">契約プログラミング</a>というクラス設計を行えるため、従来より安全性や保守性が増す</li>
</ul>

<p>Perlで最も有名なWAF（ウェブアプリケーションフレームワーク<span class="en">/Web Application Framework</span>）である<a href="http://search.cpan.org/perldoc?Catalyst"><code>Catalyst</code></a>がバージョン<code>5.8</code>以降で<code>Moose</code>を採用するなど、大規模モジュールへの適用事例も数多いので、<code>Moose</code>は業務アプリケーションへも十分に導入可能です。</p>

<p>しかし、<code>Moose</code>に基づくクラスにはPerl5の素のクラスと比較してオーバーヘッドがあります。また、本稿で紹介した<code>Moose</code>特有の構文を覚える必要もあります。</p>

<p>これに伴い、<code>Moose</code>を使うかどうかという議論が巻き起こったこともあります。それらは<a href="http://d.hatena.ne.jp/gfx/">gfxさん</a>の<a href="http://d.hatena.ne.jp/gfx/20090902/1251874374">Mooseの速度が遅いという議論のまとめと感想</a>という記事に簡潔にまとめられています。その後も、Perl論壇では以下のような考えが表明されています。</p>

<ul>
<li><a href="http://mt.endeworks.jp/d-6/2009/09/to-moose-or-not-to-moose.html">To Moose Or Not To Moose</a> : lestrratさんによる記事です。</li>
<li><a href="http://slashdot.jp/~taro-nishino/journal/492629">Mooseの為か、そうでないのか</a> : <a href="http://slashdot.jp/~taro-nishino/journal/">taro-nishinoさん</a>による上記の日本語訳です。</li>
<li><a href="http://d.hatena.ne.jp/yappo/20091105/1257390331">To Moose Or Not To Moose の邦訳を本人っぽく書き直してみた</a> : <a href="http://blog.yappo.jp/yappo/">Yappoさん</a>によるlestrratさん風の意訳です。</li>
<li><a href="http://blog.yappo.jp/yappo/archives/000709.html">Mooseを使うべきでない理由とMooseを使う理由</a> : Yappoさんによる記事です。</li>
</ul>

<p>こうした議論に一通り目を通した上で、自分なりに（或いは会社やチーム内で）案件毎の<code>Moose</code>の採否を決めることをお勧めします。</p>

<h3><span id="see_also">関連情報/See Also</span></h3>

<h4><span id="manuals_for_moose"><code>Moose</code>マニュアル/Manuals for <code>Moose</code></span></h4>

<p>この文書はあくまで「つまみ食い」したものに過ぎません。<code>Moose</code>にはまだまだ色々な機能や作法があります。実用する前に以下の一次資料へ一通り目を通しておくことをお勧めします。</p>

<ul>
<li><a href="http://search.cpan.org/dist/Moose/">Moose at Search CPAN</a> : <code>Moose</code>には豊富なマニュアル(<a href="http://search.cpan.org/perldoc?Moose::Manual"><code>Moose::Manual</code></a>)やクックブック(<a href="http://search.cpan.org/perldoc?Moose::Cookbook"><code>Moose::Cookbook</code></a>)がPODとして付属しています。（英語）</li>
<li><a href="http://perldoc.perlassociation.org/pod/Moose-Doc-JA/">Mooseマニュアル日本語版</a> : 上記文書の日本語版です。<a href="http://japan.perlassociation.org/jpa">JPA</a>による翻訳プロジェクトの一環として、<a href="http://d.hatena.ne.jp/charsbar/">charsbarさん</a>によって訳出されました。</li>
</ul>

<h4><span id="sources_about_moose"><code>Moose</code>関連のその他の情報源/Sources about <code>Moose</code></span></h4>

<ul>
<li><a href="http://moose.perl.org/">Moose homepage</a> （英語）<!-- http://www.iinteractive.com/moose/へリダイレクトされますが、リダイレクト先の変更もあり得るため、リダイレクト元の（ほぼ永遠に存在するであろう）perl.orgのURLへハイパーリンクを張っています。 --></li>
<li>moose@perl.org : <code>Moose</code>のメーリングリストです。（英語）</li>
<li>#moose@irc.perl.org : <code>Moose</code>のIRCチャネルです。（英語）</li>
<li><a href="http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo/moose-presentations.git;a=tree;f=moose-class">Introduction to Moose</a> : <code>Moose</code>入門研修のスライドと演習問題です。（英語）</li>
<li><a href="http://github.com/gardejo/moose-presentations">Moose入門研修</a> : 上記の拙訳による日本語版です。</li>
<li>『<a href="http://www.amazon.co.jp/dp/4798119172">モダンPerl入門</a>』 : JPA代表の<a href="http://mt.endeworks.jp/d-6/">lestrratさん</a>入魂の一冊。<a href="http://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3_%28%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%29">GoFデザインパターン</a>を<code>Moose</code>で実装するなど、<code>Moose</code>の活用法も幅広く言及されています。お勧め。</li>
<li><a href="http://tinyurl.com/moosequickref">Moose Quick-Ref Card</a> : <a href="http://sites.google.com/site/gorwits/">Oliver Gorwitsさん</a>による<code>Moose</code>のチートシートです。（英語）<!-- URLはカードに記載されている値を尊重しています。 --></li>
<li><a href="http://blog.eorzea.asia/2010/02/post_91.html">Moose &amp; Mouseの私家版クイックリファレンスシート</a> : 上記にインスパイアされた拙作のチートシートです。PDFとODTで公開しています。</li>
</ul>

<h4><span id="the_fastest_ways_for_mastering_basic_perl_grammar">Perl関連の基礎文法最速マスター/The Fastest Ways for Mastering Basic Perl Grammar</span></h4>

<ul>
<li><a href="http://d.hatena.ne.jp/perlcodesample/20091226/1264257759">Perl基礎文法最速マスター - Perl入門～サンプルコードによるPerl入門～</a></li>
<li><a href="http://d.hatena.ne.jp/chaichanPaPa/20100206/1265436393">Perlオブジェクト基礎文法最速マスター - 燈明日記</a></li>
</ul>

<h4><span id="collection_of_the_fastest_ways_for_mastering_a_programming_language">基礎文法最速マスターのまとめ/Collection of the Fastest Ways for Mastering a Programming Language</span></h4>

<ul>
<li><a href="http://d.hatena.ne.jp/seikenn/20100203/programmingMaster">プログラミング基礎文法最速マスターまとめ - ネットサービス研究室</a></li>
<li><a href="http://d.hatena.ne.jp/FKD000/20100201/1265023171">各種言語による基礎文法最速マスターまとめ - きまぐれメモ</a></li>
<li><a href="http://d.hatena.ne.jp/gifnksm/20100202/1265105961">(基礎|変態)文法最速マスターシリーズのまとめ - なんとなく日記</a></li>
</ul>

<h4><span id="errata">正誤一覧/Errata</span></h4>

<p>誤りや漏れが少なからずありました。<em>ごめんなさい。</em></p>

<ul>
<li>題名で「基本文法」の"Basic Grammar of"への訳出がすっかり抜け落ちていました。パーマリンクを今から変えるのは忍びないので、題名もこのままとしておきます。</li>
<li><code>requires</code>とJavaのインターフェースとの類似性についての記述を、ロールの説明部へ移動しました。さらに、ロールに実装するメソッドについてRubyのミックスインとの類似性を追記しました。また、ロールの素晴らしさについても追記しました。</li>
<li><code>has [ @attribute_names ] =&gt; ...</code>構文を追記しました。</li>
<li><code>extends</code>の<code>use base</code>との相違点の記述について、gfxさんからご指摘（<a href="http://twitter.com/__gfx__/status/9281558737">1</a>, <a href="http://twitter.com/__gfx__/status/9281591334">2</a>）をいただきました。<code>@ISA</code>を上書きすることと、<code>@ISA</code>を動的に（実行時に）再設定しない作法とを混同して書いてしまいました。敢えて書くまでもない相違点だと考えたので削除しました。</li>
<li>dannさんのパッチに相当する、メソッドモディファイヤーの正規表現指定に言及しました。</li>
<li>gfxさんが<code>Mouse</code>でのmethod modifiers + regexp構文の対応について<a href="http://twitter.com/__gfx__/status/9282285825">言及されていた</a>ので、取り込ませていただきました。</li>
<li><code>accessor</code>には<code>is =&gt; 'rw'</code>が必須であることを記述しました。</li>
<li>型の例文の<code>my $foo = Foo-&gt;new(baz =&gt; 1);</code>の初期化引数<code>baz</code>を<code>bar</code>に直しました。また、真偽値ではなく数値であることを明確に表現するため、<code>1</code>を<code>42</code>にしました。</li>
<li>Role型が<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.84"><code>Moose 0.84+</code></a>で非推奨になったことを追記しました。</li>
<li><code>Counter</code>ネイティブトレートの記述が抜けていたので追加しました。</li>
<li><code>String</code>ネイティブトレートの<code>replace</code>と<code>match</code>で、正規表現のパターンマッチ演算子xmsiが自動適用されているような補記が誤っていたので改めました。</li>
<li><code>String</code>ネイティブトレートの<code>clear</code>で、clearer methodとの混同に注意を促す記述は削除しました。</li>
<li><code>Array</code>ネイティブトレートの<code>uniq</code>の元ネタは<a href="http://search.cpan.org/perldoc?List::Util"><code>List::Util</code></a>ではなく<a href="http://search.cpan.org/perldoc?List::MoreUtils"><code>List::MoreUtils</code></a>でした。いつも間違えます......（コードで書き間違えないようにするには<a href="http://search.cpan.org/perldoc?Util::Any"><code>Util::Any</code></a>がお勧め）。</li>
<li><code>Array</code>ネイティブトレートの<code>natatime</code>の記述が抜けていたので追加しました。</li>
<li><code>Array</code>ネイティブトレートの<code>reduce</code>, <code>shuffle</code>, <code>uniq</code>, <code>natatime</code>が<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.89_02"><code>Moose 0.89_02+</code></a>であることを追記しました。</li>
<li><code>Code</code>ネイティブトレートが<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#0.90"><code>Moose 0.90+</code></a>であることを追記しました。</li>
<li><a href="http://search.cpan.org/perldoc?MouseX::NativeTraits"><code>MouseX::NativeTraits</code></a>への言及を加えました。</li>
<li><code>BUILD</code>の"isaやrequiredへの対策は"に「など」を加えました。<code>does</code>なども関係しているためです。</li>
<li><code>Mouse</code>のロードが速い理由について、<a href="http://d.hatena.ne.jp/tokuhirom/">tokuhiromさん</a>から<a href="http://d.hatena.ne.jp/tokuhirom/20100218">ご指摘をいただきました</a>。どうもありがとうございます。私の単なる憶測による記述でしたので、記述を改めました。</li>
<li><code>Any::Moose</code>の"将来的にMooseが高速化した場合"に「さらに」を加えました。JPA後援のgfxさんの高速化案件など、<code>Moose</code>や<code>Class::MOP</code>は定期的な高速化が図られているためです。</li>
<li><code>with</code>の<code>alias</code>, <code>exclude</code>の引数を<a href="http://search.cpan.org/perldoc?Moose::Manual::Delta#Version_0.89_01"><code>Moose 0.89_01+</code></a>対応の作法に直して<code>-alias</code>, <code>-excludes</code>にしました。</li>
<li>『モダンPerl入門』を<code>Moose</code>の観点でお勧めする理由を補記しました。</li>
<li>拙作のチートシートを参考情報に加えました。</li>
<li>目次の<code>a</code>要素の<code>href</code>属性に絶対URLを追加しました。個別エントリー以外のページでのハイパーリンクが効かないためです。</li>
<li>目次などから飛ぶ見出し(heading)用<code>id</code>属性は、<code>a</code>要素ではなく<code>span</code>要素に付けるようにしました。</li>
</ul>]]>
    </content>
</entry>

<entry>
    <title>CPAN モジュールインストール時にデフォルトで yes と答える方法</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2010/01/cpan_yes.html" />
    <id>tag:perl-mongers.org,2010://1.94</id>

    <published>2010-01-02T15:43:22Z</published>
    <updated>2010-01-02T16:06:20Z</updated>

    <summary>明けましておめでとうございます！ mumumu です。 僕は普段 Perl を使...</summary>
    <author>
        <name>mumumu.myopenid.com</name>
        <uri>http://mumumu.myopenid.com/</uri>
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>明けましておめでとうございます！ <a href="http://mumumuorg.blogspot.com/">mumumu</a> です。</p>
<br />
<p>僕は普段 Perl を使ってないんだけど、たまに CPAN module をインストールする機会があります。その際に毎回うざいなって思うのが、依存関係にあるモジュールをインストールしますか？ って以下のように聞かれること。このときエンターキーを連打したくないわけです。</p>
<pre>
---- Unsatisfied dependencies detected during ----
----       MIYAGAWA/XML-Atom-0.37.tar.gz      ----
    XML::LibXML [requires]
    XML::XPath [requires]
Shall I follow them and prepend them to the queue
of modules we are processing right now? [yes]
</pre>
<p>つまり僕がやりたいのは、こうした CPAN の問いかけに自動で yes と答えて貰うようにしたいということ。 </p>
<p>ちょっとぐぐったら yes コマンドを使ったりとか、PERL_AUTOINSTALL=&#39;--defaultdeps&#39; の環境変数を設定したりだとかいろいろ出てきたけど、<a href="http://d.hatena.ne.jp/tokuhirom">tokuhiromさん</a> に教えて貰った以下の方法が一番効いたので書いておくことにしますです。</p>
<pre>
$ sudo perl -MCPAN -e shell
cpan&gt; o conf prerequisites_policy follow
cpan&gt; o conf commit
</pre>
<p> 多分慣れた人には当然なんだろうけど、たまに使う俺はちょっと感動しますた(´ー｀; )</p>

]]>
        
    </content>
</entry>

<entry>
    <title>Catalyst::Controller::Resources で Chaind を楽しよう</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2009/06/catalyst-controller-resources.html" />
    <id>tag:perl-mongers.org,2009://1.93</id>

    <published>2009-06-14T15:43:31Z</published>
    <updated>2009-06-14T15:59:31Z</updated>

    <summary>どうも、お久しぶりの vkgtaro です。自分の blog に書こうかと思った...</summary>
    <author>
        <name>vkgtaro.jp</name>
        <uri>http://vkgtaro.jp/</uri>
    </author>
    
    <category term="ctalystcatalystcontrollerresources" label="Ctalyst Catalyst::Controller::Resources" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>どうも、お久しぶりの vkgtaro です。自分の blog に書こうかと思ったんだけど、購読者数が多いこちらに書くよ！</p>
<br />
<p>JPA の活動とか charsbar さんの連載で Catalyst が盛り上がってきてますね。と言うことで、Catalyst::Controller::Resources を紹介したいと思います。（JPA のセミナーでは Action::REST が紹介されてたようだけど、個人的には Resources が好きです。Resources 使うために Catalyst 使ってると言っても過言じゃないくらい。）</p>
<br />
<p>Resources を使うと HTTP method の GET / POST / PUT / DELETE に応じた Chained がカンタンに作れます。Ruby on Rails をやったことある人だと map.resources と言えばわかるのかな？　僕は rails やったことがないのでわからないんですけれども。</p>
<br />
<p>使い方はこんな風に Catalyst::Controller の代わりに Catalyst::Controller::Resources を使うだけ。</p>

<pre>
<span class="synStatement">package</span><span class="synType"> Jnsn::Controller::Articles;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>parent <span class="synConstant">&#39;Catalyst::Controller::Resources&#39;</span>;
</pre>

<p>これで、以下のような URI / method と action のマップができる。</p>

<table>
<tr>



</tr>
<tr>
<td> /articles                   </td>
<td> get     </td>
<td> Articles#list </td>
</tr>
<tr>
<td> /articles/new               </td>
<td> get     </td>
<td> Articles#post </td>
</tr>
<tr>
<td> /articles                   </td>
<td> post    </td>
<td> Articles#create </td>
</tr>
<tr>
<td> /articles/{article_id}      </td>
<td> get     </td>
<td> Articles#show </td>
</tr>
<tr>
<td> /articles/{article_id}/edit </td>
<td> get     </td>
<td> Articles#edit </td>
</tr>
<tr>
<td> /articles/{article_id}      </td>
<td> put     </td>
<td> Articles#update </td>
</tr>
<tr>
<td> /articles/{article_id}      </td>
<td> delete  </td>
<td> Articles#destroy </td>
</tr>
</table>

<p>
これは、対応する action を作らなければ実際にはチェーンされません。<br />
なので必要ない URI は作りたくないという人も安心です。
</p>
<br />
<p>ちなみに {article_id} は、3番めの引数として渡ってくるよ。</p>

<pre>
<span class="synComment"># PUT /articles/{article_id}</span>
<span class="synStatement">sub</span><span class="synIdentifier"> update </span>{
    <span class="synStatement">my</span> (<span class="synIdentifier">$self</span>, <span class="synIdentifier">$c</span>, <span class="synIdentifier">$article_id</span>) = <span class="synIdentifier">@_</span>;
}
</pre>

<p>この id を特定して何かの操作をするものを member, そうじゃないやつを collection と REST では言うみたいですね。（内部的には member と colllection に chain してるのは起動時のデバッグログでわかりますね。）</p>
<br />
<p>Resources の魅力はまだあります。articles に属している comments を作りたいなぁ、URI は /articles/{article_id}/comments/{comment_id} みたくしたいなぁ、と思ったら Comments コントローラ内でこうすればいいです。</p>

<pre>
<span class="synStatement">package</span><span class="synType"> Jnsn::Controller::Articles::Comments;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;

<span class="synStatement">use </span>parent <span class="synConstant">&#39;Catalyst::Controller::Resources&#39;</span>;

__PACKAGE__-&gt;config(
    <span class="synConstant">belongs_to </span>=&gt; <span class="synConstant">&#39;Articles&#39;</span>,
);
</pre>

<p>こうすることによって Articles::Comments は Catalyst のチェーン的に Articles に属します。</p>

<table>
<tr>



</tr>
<tr>
<td> /articles/{article_id}/comments </td>
<td> get </td>
<td> Articles::Comments#list </td>
</tr>
<tr>
<td> /articles/{article_id}/comments/new </td>
<td> get </td>
<td> Articles::Comments#post </td>
</tr>
<tr>
<td> /articles/{article_id}/comments </td>
<td> post </td>
<td> Articles::Comments#create </td>
</tr>
<tr>
<td> /articles/{article_id}/comments/{comment_id} </td>
<td> get </td>
<td> Articles::Comments#show </td>
</tr>
<tr>
<td> /articles/{article_id}/comments/{comment_id}/edit </td>
<td> get </td>
<td> Articles::Comments#edit </td>
</tr>
<tr>
<td> /articles/{article_id}/comments/{comment_id} </td>
<td> put </td>
<td> Articles::Comments#update </td>
</tr>
<tr>
<td> /articles/{article_id}/comments/{comment_id} </td>
<td> delete </td>
<td> Articles::Comments#destroy </td>
</tr>
</table>

<p>
さらに、マップにない action を追加したいなぁと思ったら、config で追加しましょう。<br />
article 追加時の確認画面と編集時の確認画面を追加してみます。
</p>

<pre>
<span class="synComment"># Jnsn::Controller::Articles;</span>
__PACKAGE__-&gt;config(
    <span class="synConstant">collection </span>=&gt; {
        <span class="synConstant">confirm </span>=&gt; <span class="synConstant">&#39;post&#39;</span>,
    },
    <span class="synConstant">member </span>=&gt; {
        <span class="synConstant">confirm_edit </span>=&gt; <span class="synConstant">&#39;post&#39;</span>,
    }
);

<span class="synComment"># POST /articles/confirm</span>
<span class="synStatement">sub</span><span class="synIdentifier"> confirm </span>{
    <span class="synStatement">my</span> (<span class="synIdentifier">$self</span>, <span class="synIdentifier">$c</span>) = <span class="synIdentifier">@_</span>;
}

<span class="synComment"># POST /articles/{article_id}/confirm_edit</span>
<span class="synStatement">sub</span><span class="synIdentifier"> confirm_edit </span>{
    <span class="synStatement">my</span> (<span class="synIdentifier">$self</span>, <span class="synIdentifier">$c</span>, <span class="synIdentifier">$article_id</span>) = <span class="synIdentifier">@_</span>;
}
</pre>

<p>ね、カンタンでしょう？</p>
<br />
<p>ブラウザーから PUT と DELETE 送れない問題は <a href="http://search.cpan.org/~drolsky/Catalyst-Request-REST-ForBrowsers/">Catalyst::Request::REST::ForBrowser</a> を使うとうまくできるよ。</p>
<p>（参考：<a href="http://d.hatena.ne.jp/ZIGOROu/20090124/1232810879">Catalyst::Controller::Resources でオーバーロード POST を使いたい - Yet Another Hackadelic</a>）</p>
<br />
<p>なお、この記事は Catalyst 5.80004, Catalyst::Controller::Resources 0.07 で書いてます。Cat 5.7 系で Resources 使うときは 0.04 を使うといいですよ！</p>

]]>
        
    </content>
</entry>

<entry>
    <title>__DATA__ で色んなことを考えてみよう</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2009/01/__data.html" />
    <id>tag:perl-mongers.org,2009://1.89</id>

    <published>2009-01-19T12:09:00Z</published>
    <updated>2009-01-19T12:35:38Z</updated>

    <summary>こんばんは。ビンゴ中西です。 Perlでは、 __DATA__ と書いた部分より...</summary>
    <author>
        <name>ビンゴ中西</name>
        <uri>http://www.hatena.ne.jp/bingo_nakanishi_perl/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>こんばんは。ビンゴ中西です。</p>
<br />

<p>Perlでは、</p>
<pre>
<span class="synComment">__DATA__</span>
</pre>
<p>と書いた部分より下は、</p>
<p>まるで、すでにファイルをopenしたかのように使えます。</p>

<h4> 例1</h4>
<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use </span>Data::Dumper;

<span class="synStatement">while</span>(<span class="synIdentifier">&lt;DATA&gt;</span>){
  <span class="synStatement">print</span> <span class="synIdentifier">$_</span>;
}


<span class="synComment">__DATA__</span>
<span class="synComment">ここは、ファイルのように</span>
<span class="synComment">扱えますよ！</span>
</pre>

<h4> 結果</h4>
<pre>
ここは、ファイルのように
扱えますよ！
</pre>


<p>こんな感じです。</p>
<p>ファイルを使って本処理を進めるまえに、ちょっとしたことを考えるのに便利です。</p>


<h4> データ構造をどのようにするか？</h4>
<p>たとえば、CSVのファイルをどのような構造で持つか</p>
<p>といったことは、</p>

<h4> 例2</h4>
<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use </span>Data::Dumper;

<span class="synStatement">my</span> <span class="synIdentifier">@c</span>;
<span class="synStatement">while</span>(<span class="synIdentifier">&lt;DATA&gt;</span>){
  <span class="synStatement">chomp</span> <span class="synIdentifier">$_</span>;
  <span class="synStatement">push</span> <span class="synIdentifier">@c</span>, [<span class="synStatement">split</span> <span class="synConstant">&#39;,&#39;</span>, <span class="synIdentifier">$_</span>];
}
<span class="synStatement">print</span> <span class="synIdentifier">Dumper</span> <span class="synIdentifier">\@c</span>;


<span class="synComment">__DATA__</span>
<span class="synComment">OK,bbbb,ccc</span>
<span class="synComment">NG,eee,ffff</span>
</pre>

<h4> 結果</h4>
<pre>
$VAR1 = [
          [
            &#39;OK&#39;,
            &#39;bbbb&#39;,
            &#39;ccc&#39;
          ],
          [
            &#39;NG&#39;,
            &#39;eee&#39;,
            &#39;ffff&#39;
          ]
        ];
</pre>

<h4> 例3</h4>
<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use </span>Data::Dumper;

<span class="synStatement">my</span> <span class="synIdentifier">$c</span> = {};
<span class="synStatement">while</span>(<span class="synIdentifier">&lt;DATA&gt;</span>){
  <span class="synStatement">chomp</span> <span class="synIdentifier">$_</span>;
  <span class="synStatement">my</span> <span class="synIdentifier">@d</span>   = <span class="synStatement">split</span> <span class="synConstant">&#39;,&#39;</span>, <span class="synIdentifier">$_</span>;
  <span class="synStatement">my</span> <span class="synIdentifier">$key</span> = <span class="synStatement">shift</span> <span class="synIdentifier">@d</span>;
  <span class="synIdentifier">$c</span>-&gt;{<span class="synIdentifier">$key</span>} = <span class="synIdentifier">\@d</span>;
}
<span class="synStatement">print</span> <span class="synIdentifier">Dumper</span> <span class="synIdentifier">$c</span>;


<span class="synComment">__DATA__</span>
<span class="synComment">OK,bbbb,ccc</span>
<span class="synComment">NG,eee,ffff</span>
</pre>

<h4> 結果</h4>
<pre>
$VAR1 = {
          &#39;OK&#39; =&gt; [
                    &#39;bbbb&#39;,
                    &#39;ccc&#39;
                  ],
          &#39;NG&#39; =&gt; [
                    &#39;eee&#39;,
                    &#39;ffff&#39;
                  ]
        };
</pre>

<p>などと書いてみて、考えることができます。</p>

<h4> もっと考えをおし進めて</h4>
<p>もっと考えをおし進めて、ファイルの内容と処理をどう結びつけようか</p>
<p>なんてことも　こんな風に考えれます。</p>

<h4> 例4</h4>
<pre>
<span class="synStatement">use strict</span>;

<span class="synStatement">my</span> <span class="synIdentifier">$f</span> = {
         <span class="synConstant">&#39;OK&#39;</span> =&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ <span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@_</span><span class="synConstant">&quot;</span> . <span class="synConstant">&#39;は 大丈夫です&#39;</span>, <span class="synConstant">&quot;</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>; },
         <span class="synConstant">&#39;NG&#39;</span> =&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ <span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@_</span><span class="synConstant">&quot;</span> . <span class="synConstant">&#39;は ダメです&#39;</span>,   <span class="synConstant">&quot;</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>; }
        };

<span class="synStatement">my</span> <span class="synIdentifier">$c</span> = {};
<span class="synStatement">while</span>(<span class="synIdentifier">&lt;DATA&gt;</span>){
  <span class="synStatement">chomp</span> <span class="synIdentifier">$_</span>;
  <span class="synStatement">my</span> <span class="synIdentifier">@d</span>   = <span class="synStatement">split</span> <span class="synConstant">&#39;,&#39;</span>, <span class="synIdentifier">$_</span>;
  <span class="synStatement">my</span> <span class="synIdentifier">$key</span> = <span class="synStatement">shift</span> <span class="synIdentifier">@d</span>;
  <span class="synIdentifier">$f</span>-&gt;{<span class="synIdentifier">$key</span>}-&gt;(<span class="synIdentifier">@d</span>);
}


<span class="synComment">__DATA__</span>
<span class="synComment">OK,bbbb,ccc</span>
<span class="synComment">NG,eee,ffff</span>
</pre>

<h4>  結果</h4>
<pre>
bbbb cccは 大丈夫です
eee ffffは ダメです
</pre>


<p>ファイルを open したりといったことを考えなくていいですし、</p>
<p>考えるファイルの中身も、ソースと同じファイルに入っているので、編集が容易です。</p>

]]>
        
    </content>
</entry>

<entry>
    <title>Re: 高階関数の考え方でmapを見てみる</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2009/01/re_map.html" />
    <id>tag:perl-mongers.org,2009://1.88</id>

    <published>2009-01-15T03:45:13Z</published>
    <updated>2009-01-15T06:02:12Z</updated>

    <summary>高階関数の考え方でmapを見てみる 記事の意図から外れちゃうかもしれないけど、、...</summary>
    <author>
        <name>http://coderepos.org/share/wiki/Committers/yappo</name>
        <uri>http://coderepos.org/share/wiki/Committers/yappo</uri>
    </author>
    
    <category term="dankogai" label="dankogai" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p><a href="http://perl-mongers.org/2009/01/map.html">高階関数の考え方でmapを見てみる</a></p>
<p>記事の意図から外れちゃうかもしれないけど、、、</p>
<br />
<p>それprototypeでできるよ。</p>

<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;

<span class="synStatement">sub</span><span class="synIdentifier"> my_map (&amp;@) </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$code</span> = <span class="synStatement">shift</span>;
    <span class="synStatement">my</span> <span class="synIdentifier">@array</span>;
    <span class="synStatement">for</span> <span class="synStatement">my</span> <span class="synIdentifier">$val</span> (<span class="synIdentifier">@_</span>) {
        <span class="synStatement">push</span> <span class="synIdentifier">@array</span>, <span class="synIdentifier">$code</span>-&gt;(<span class="synIdentifier">$val</span>);
    }
    <span class="synStatement">return</span> <span class="synIdentifier">@array</span>;
}

<span class="synStatement">my</span> <span class="synIdentifier">@c</span> = <span class="synConstant">1.</span>.<span class="synConstant">4</span>;
my_map { <span class="synStatement">print</span> <span class="synConstant">&quot;aa</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>; } <span class="synIdentifier">@c</span>;

<span class="synStatement">print</span> <span class="synConstant">&quot;---------</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
<span class="synStatement">my</span> <span class="synIdentifier">@d</span> = my_map { <span class="synIdentifier">$_</span>[<span class="synConstant">0</span>] ** <span class="synConstant">2</span> } <span class="synIdentifier">@c</span>;
<span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@d</span><span class="synConstant">&quot;</span>, <span class="synConstant">&quot;</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;

<span class="synStatement">print</span> <span class="synConstant">&quot;--------</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
my_map  { <span class="synIdentifier">$_</span>[<span class="synConstant">0</span>]++ } <span class="synIdentifier">@c</span>;
<span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@c</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
</pre>


<pre>
 perl ./bingo.pl 
aa
aa
aa
aa
---------
1 4 9 16
--------
2 3 4 5
</pre>

]]>
        
    </content>
</entry>

<entry>
    <title>高階関数の考え方でmapを見てみる</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2009/01/map.html" />
    <id>tag:perl-mongers.org,2009://1.87</id>

    <published>2009-01-14T12:42:08Z</published>
    <updated>2009-01-14T13:24:29Z</updated>

    <summary>ビンゴ中西と申します。 関数が、関数に渡せることが書かれていましたので、 map...</summary>
    <author>
        <name>ビンゴ中西</name>
        <uri>http://www.hatena.ne.jp/bingo_nakanishi_perl/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>ビンゴ中西と申します。</p>
<br />
<p>関数が、関数に渡せることが書かれていましたので、</p>
<p>mapのことを考えたいと思います。</p>
<pre>
<span class="synIdentifier">@c</span> = <span class="synStatement">map</span> { <span class="synIdentifier">$_</span>*<span class="synConstant">2</span> } <span class="synConstant">1.</span>.<span class="synConstant">3</span>;
<span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@c</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
</pre>
<p>結果：</p>
<pre>
2 4 6
</pre>

<p>これって、</p>
<p>map の {  } の部分に sub を付けてみると、</p>
<p>まあ、無名関数を map に与えたみたい！</p>
<br />
<p>ということで、map のように振る舞う。my_mapという関数を簡単に書いてみました。</p>


<pre>
<span class="synStatement">use strict</span>;

<span class="synStatement">sub</span><span class="synIdentifier"> my_map</span>{
  <span class="synStatement">my</span> <span class="synIdentifier">@array</span>;
  <span class="synStatement">for</span>(@{<span class="synIdentifier">$_</span>[<span class="synConstant">1</span>]}){
    <span class="synStatement">push</span> <span class="synIdentifier">@array</span>, <span class="synIdentifier">$_</span>[<span class="synConstant">0</span>]-&gt;(<span class="synIdentifier">$_</span>);
  }
  <span class="synStatement">return</span> <span class="synIdentifier">@array</span>;
}

<span class="synStatement">my</span> <span class="synIdentifier">@c</span> = <span class="synConstant">1.</span>.<span class="synConstant">4</span>;
my_map(<span class="synIdentifier"> </span><span class="synStatement">sub</span>{ <span class="synStatement">print</span> <span class="synConstant">&quot;aa</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>; }, <span class="synIdentifier">\@c</span>);

<span class="synStatement">print</span> <span class="synConstant">&quot;---------</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
<span class="synStatement">my</span> <span class="synIdentifier">@d</span> = my_map(<span class="synIdentifier"> </span><span class="synStatement">sub</span>{ <span class="synIdentifier">$_</span>[<span class="synConstant">0</span>] ** <span class="synConstant">2</span> }, <span class="synIdentifier">\@c</span>);
<span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@d</span><span class="synConstant">&quot;</span>, <span class="synConstant">&quot;</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;

<span class="synStatement">print</span> <span class="synConstant">&quot;--------</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
my_map(<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ <span class="synIdentifier">$_</span>[<span class="synConstant">0</span>]++ }, <span class="synIdentifier">\@c</span> );
<span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">@c</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
</pre>

<p>結果：</p>
<pre>
aa
aa
aa
aa
---------
1 4 9 16
--------
2 3 4 5
</pre>

<p>mapに似たような機能で grep というのがありますが、おなじように</p>
<p>grep に与える {  } の部分はなにか関数を渡しているように感じられます。</p>
<br />
<p>私は、関数に、関数が渡せるということを知ってmapがすんなり理解できた気がしました。</p>
<br />
<p>私の下手な関数は使わずに、ぜひ、map と grep　という機能をどんどん使って楽しいプログラミングを行いましょう〜</p>
<br />

<p>※本記事は、mapの代替品を作ったというわけや、mapを完全に再現したというわけではありません。</p>

]]>
        
    </content>
</entry>

<entry>
    <title>関数は第一級オブジェクト</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2009/01/post_5.html" />
    <id>tag:perl-mongers.org,2009://1.86</id>

    <published>2009-01-13T17:28:44Z</published>
    <updated>2009-01-13T18:38:44Z</updated>

    <summary><![CDATA[Perlの関数は第一級オブジェクトなので&quot;物&quot;として扱えます...]]></summary>
    <author>
        <name>hiratara.dyndns.org</name>
        <uri>http://d.hatena.ne.jp/hiratara</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>Perlの関数は第一級オブジェクトなので&quot;物&quot;として扱えます。関数オブジェクトは処理内容であり、任意のタイミングでそれを実行することができます。</p>
<br />
<p>Perlでは関数リファレンスと呼ばれるものによって関数オブジェクトを表します。関数リファレンスは、関数名を与えないsubで生成したり、関数名に \&amp; をつけることで取得できます。</p>

<pre>
<span class="synStatement">my</span> <span class="synIdentifier">$hello_function</span> =<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
    <span class="synStatement">print</span> <span class="synConstant">&quot;hello</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
};

<span class="synStatement">sub</span><span class="synIdentifier"> bye </span>{
    <span class="synStatement">print</span> <span class="synConstant">&quot;bye</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
};

<span class="synStatement">my</span> <span class="synIdentifier">$bye_function</span>   = <span class="synIdentifier">\&amp;bye</span>;

<span class="synIdentifier">$hello_function</span>-&gt;();
<span class="synIdentifier">$bye_function</span>-&gt;();
</pre>

<p>関数は&quot;物&quot;なので、もっと自由なことができます。例えば、他の関数にお好みの関数を作ってもらうことができます。</p>

<pre>
<span class="synStatement">sub</span><span class="synIdentifier"> greeting_function</span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$greeting</span> = <span class="synStatement">shift</span>;
    <span class="synStatement">return</span><span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
        <span class="synStatement">print</span> <span class="synConstant">&quot;</span><span class="synIdentifier">$greeting</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>;
    };
}

<span class="synStatement">my</span> <span class="synIdentifier">$hello_function</span> = greeting_function(<span class="synConstant">&#39;hello&#39;</span>);
<span class="synStatement">my</span> <span class="synIdentifier">$bye_function</span>   = greeting_function(<span class="synConstant">&#39;bye&#39;</span>);

<span class="synIdentifier">$hello_function</span>-&gt;();
<span class="synIdentifier">$bye_function</span>-&gt;();
</pre>

<p>ここでもう一つ、関数はクロージャであると言う性質が出て来ています。greeting_functionで生成する関数の中に $greeting が登場していますが、これは外の世界の変数です。Perlの関数はクロージャとなるように実装されていますので、生成される関数は外の世界の変数 $greeting をそのまま参照し続けます。</p>
<br />
<p>クロージャの性質を使うと、生成されたコンテキストによって処理内容が変わる関数を作成できます。先ほどの例だと、引数が &#39;hello&#39; の時は&#39;hello&#39;を表示する関数、引数が&#39;bye&#39;の時は&#39;bye&#39;を表示する処理がそれぞれ生成されました。</p>
<br />
<p>逆に、関数の呼び出しによって関数作成元のコンテキストに影響を与えることも出来ます。</p>

<pre>
<span class="synStatement">sub</span><span class="synIdentifier"> call_with_greeting</span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$function</span> = <span class="synStatement">shift</span>;
    <span class="synIdentifier">$function</span>-&gt;(<span class="synConstant">&#39;hello&#39;</span>);
    <span class="synIdentifier">$function</span>-&gt;(<span class="synConstant">&#39;bye&#39;</span>);
}

<span class="synStatement">my</span> <span class="synIdentifier">@greetings</span>;
<span class="synStatement">my</span> <span class="synIdentifier">$callback</span> =<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$greeting</span> = <span class="synStatement">shift</span>;
    <span class="synStatement">push</span> <span class="synIdentifier">@greetings</span>, <span class="synIdentifier">$greeting</span>;
}

call_with_greeting(<span class="synIdentifier">$callback</span>);

<span class="synStatement">print</span> <span class="synStatement">map</span> {<span class="synConstant">&quot;</span><span class="synIdentifier">$_</span><span class="synSpecial">\n</span><span class="synConstant">&quot;</span>} <span class="synIdentifier">@greetings</span>;
</pre>

<p>$callbackが呼ばれる度に、@greetingsに挨拶文が加えられます。call_with_greeting関数内で$callbackを呼び出すことで、call_with_greeting関数外(生成した時のコンテキスト)に含まれる@greetingsを変化させていることに注目して下さい。</p>
<br />

<p>関数オブジェクトから新しい関数オブジェクトを作る関数を揃えると、以下のようなコーディングもできます。</p>

<pre>
sub greeting_function{
    my ($greeting, $print_function) = @_;
    return sub {
        $print_function-&gt;($greeting);
    }
}

sub with_newline{
    my $function = shift;
    return sub {
        $function-&gt;(map {&quot;$_\n&quot;} @_);
    }
}

sub print{
    print @_;
}

sub executer{
    my @functions = @_;
    $_-&gt;() foreach @functions;
}

my $hello_function = greeting_function(&#39;hello&#39;, with_newline(\&amp;print));
my $bye_function   = greeting_function(&#39;bye&#39;  , with_newline(\&amp;print));

executer($hello_function, $bye_function);
</pre>

<p>与えられたwith_newline、greeting_functionといった道具を駆使して、print関数から目的の関数を作ってます。</p>
<br />
<p>そして、メインルーチンでは関数の作成だけに専念し、実行に関してはexecuterに任せています。このように、処理を作成する場所と実行する場所を分離することも出来ます。</p>

]]>
        
    </content>
</entry>

<entry>
    <title>実用！ TypePadで複数blogにカテゴリー追加</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/12/_typepadblog.html" />
    <id>tag:perl-mongers.org,2008://1.85</id>

    <published>2008-12-26T03:21:40Z</published>
    <updated>2008-12-26T03:37:33Z</updated>

    <summary>クリスマス終わりましたね！ しらんけど。 ということで、年末なんで、メンテナンス...</summary>
    <author>
        <name>CL</name>
        <uri>http://blog.dtpwiki.jp/dtp/</uri>
    </author>
    
    <category term="typepad" label="TypePad" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="wwwmechanize" label="WWW::Mechanize" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>クリスマス終わりましたね！ しらんけど。</p>

<p>ということで、年末なんで、メンテナンスもかねて、blogの整理をしているんですけれども、使っているサービスが、かつてBoxerBLOGだったTypePad.jpでして、これでblogを50こぐらい作っている状況なのですが、これらのblogで、投稿するときに設定できるカテゴリーを増やすとき、今までは50回blogのコントロールパネルでしこしこ入力していたわけですけれども、単純労働過ぎるので、スクリプトを作りました。</p>

<p>TypePad.jpは、その名の通り、TypePad ASPで構築されていますので、DBを直接いじれません。従って、人間が実際行うやり方をまねる方法、つまりロボットを作ることになります。</p>

<p>以下のスクリプトは、WWW::Mechanizeを使ったTypePad系blogの複数blogカテゴリ追加スクリプトとなります。</p>

<p>クリスマス前に使ったので大丈夫だと思いますが、こっちでは保証しませんのであしからず。</p>

<p>FileName: add_category.pl</p>

<pre class="prettyprint">
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
use WWW::Mechanize;
my $login_id = &#39;login_id&#39;;
my $password = &#39;password&#39;;
my $add_category_word = &#39;便座カバー&#39;;
my $base_url = &#39;https://www.typepad.jp/t/app&#39;; # TypePad.jp
# my $base_url = &#39;https://app.cocolog-nifty.com/t/app&#39;; # ココログ
my $categores_url = &quot;$base_url/weblog/configure?__mode=categories&amp;blog_id=&quot;;
my $bloglist = [
  20721, # ブログ1。ログイン後のblog一覧のソースから取得しておこう
  26969, # ブログ2
  21919, # ブログ3
];
 
# 開始
 
my $mech = WWW::Mechanize-&gt;new();     # Mechオブジェクト用意
$mech-&gt;agent_alias( &#39;Windows IE 6&#39; ); # IE6になりきる
 
# ログイン
 
$mech-&gt;get( $base_url ); # ログインする：認証ページへ
$mech-&gt;form_number( 1 ); # 認証ページの最初のフォームを選択
$mech-&gt;set_visible( $login_id, $password ); # ログイン・パスワード入力
$mech-&gt;submit(); # 送信
 
# カテゴリー追加処理
 
foreach my $blog_id (@$bloglist) { # $blog_idを$bloglistから1つずつ入力
  my $url = &quot;$categores_url$blog_id&quot;; # 各blogのカテゴリーメンテページURL生成
  print &quot;$url\n&quot;;
  $mech-&gt;get($url);      # カテゴリーメンテページに移動
  $mech-&gt;form_number(1); # カテゴリーメンテページの最初のフォームを選択
  $mech-&gt;field( &#39;category-new&#39;               # 新しいカテゴリー名を
    =&gt; encode(&#39;utf8&#39;, $add_category_word),); # 入力
  $mech-&gt;submit();       # 送信
}
 
exit;
 
__END__</pre>

これ必要な人がどんだけいるかわかりませんけれども、お使いくださいませ。]]>
        
    </content>
</entry>

<entry>
    <title>HTMLから本文を抜き出せるモジュールHTML::ExtractContent </title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/10/extract-content-from-html.html" />
    <id>tag:perl-mongers.org,2008://1.83</id>

    <published>2008-10-10T11:44:31Z</published>
    <updated>2008-10-10T12:07:30Z</updated>

    <summary>こういうの無いかなぁと思ってました。 例えば任意のサイトのサマリを作りたい時、H...</summary>
    <author>
        <name>mattn.myopenid.com</name>
        <uri>http://mattn.kaoriya.net/</uri>
    </author>
    
    <category term="htmlextractcontent" label="HTML::ExtractContent" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>こういうの無いかなぁと思ってました。</p>
<br />
<p>例えば任意のサイトのサマリを作りたい時、HTMLをテキスト化して一定文字数で削る訳ですが、どこからどこまでが本文かはそのサイト製作者の意図する所であってなかなか難しい処理かと思います。</p>
<p>今回ご紹介する<a href="http://search.cpan.org/dist/HTML-ExtractContent/">HTML::ExtractContent</a>はHTMLの内容を判断しコンテンツの本文らしき部分を抜き出せる凄いモジュールです。</p>
<p>ソースを見ましたがテキストに含めるかどうかの閾値が設定されており、かつ句読点まで判断しています。ソースはutf-8で書かれており、おそらく作者は日本人(もしくは日本通)かと思われます。</p>
<p>試しに<a href="http://perl-mongers.org/2008/09/template-refine.html">先日の記事URL</a>から本文を抜き出してみたいと思います。</p>
<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>HTML::ExtractContent;
<span class="synStatement">use </span>LWP::UserAgent;

<span class="synStatement">my</span> <span class="synIdentifier">$agent</span> = LWP::UserAgent-&gt;<span class="synStatement">new</span>;
<span class="synStatement">my</span> <span class="synIdentifier">$res</span> = <span class="synIdentifier">$agent</span>-&gt;get(<span class="synConstant">&#39;http://perl-mongers.org/2008/09/template-refine.html&#39;</span>);

<span class="synStatement">my</span> <span class="synIdentifier">$extractor</span> = HTML::ExtractContent-&gt;<span class="synStatement">new</span>;
<span class="synIdentifier">$extractor</span>-&gt;extract(<span class="synIdentifier">$res</span>-&gt;decoded_content);
<span class="synStatement">print</span> <span class="synIdentifier">$extractor</span>-&gt;as_text;
</pre>
<p>コードもこれだけ。そして実行結果。</p>
<pre>
Template::Refineというモジュールを見つけました。リンク先にある通り、ruleを使うことで簡単にテンプレートの値を置き換える事が出来ます。このモジュールの良い所は、テンプレートファイルにテンプレートエンジン専用の識別子を記述しなくて良い所。どうやって指定するかというと、XPathを使います。リンク先から引用すると
my $username = &#39;Test User&#39;;
my $rule = simple_replace {
my $node = shift;
return replace_text $node, $username;
} &#39;//*[@class=&quot;username&quot;]&#39;;
といった感じにルールを決め
$frag = $frag-&gt;process($rule);
say $frag-&gt;render;
と実行する事でテンプレートへの反映が行われます。まるでWeb::Scraperの様ですね。
今日はサンプルとして、美輪明宏のチンコの有無を返すAPIから得た結果をテンプレートに反映してみたいと思います。
まずテンプレート
&lt;p&gt;美輪明宏にチンコは...&lt;span class=&quot;miwa&quot;&gt;...&lt;/span&gt;。&lt;/p&gt;
確かにテンプレート専用の識別子は使用していません。そしてperlのコード
use strict;
use warnings;
use Encode;
use Perl6::Say;
use LWP::Simple;
use JSON;
use Template::Refine::Fragment;
use Template::Refine::Utils qw(replace_text simple_replace);
my $miwa = from_json(get &quot;http://dzfl.jp/mojo/&quot;);
my $rule = simple_replace {
my $node = shift;
return replace_text $node, encode_utf8($miwa-&gt;{miwa} ? &#39;ある&#39; : &#39;ない&#39;);
} &#39;//*[@class=&quot;miwa&quot;]&#39;;
my $frag = Template::Refine::Fragment-&gt;new_from_file(&#39;template.html&#39;);
print $frag-&gt;process($rule)-&gt;render;
HTMLのmiwaというクラス属性を持ったノードに対して&quot;ある&quot;/&quot;ない&quot;というテキストで置換しています。
簡単ですね。テンプレートエンジン専用の識別子を使用しないので、HTMLの属性値さえ決めておけば、テンプレートの殆どをデザイナさんに任せてしまう事も出来る様になります。
すばらしいですね。
</pre>
<p>ちゃんと本文が取れています。ヘッダ部やページ右にあるナビゲータの文字は含まれていません。</p>
<p>すばらしいですね。他のアプリケーションにも簡単に取り込めそうですし期待が膨らみます。</p>
<br />
<p>どなたかこれを使ったウェブサービスを作ってみませんか。</p>

]]>
        
    </content>
</entry>

<entry>
    <title>実用！ Perlでクロネコヤマト荷物照会</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/09/perl-kuronekoyamato.html" />
    <id>tag:perl-mongers.org,2008://1.82</id>

    <published>2008-09-21T09:44:06Z</published>
    <updated>2008-09-23T17:49:05Z</updated>

    <summary>仕事をしていると、荷物を宅配便で送る業務っていうのがあるんですけれども、宅配便業...</summary>
    <author>
        <name>CL</name>
        <uri>http://blog.dtpwiki.jp/dtp/</uri>
    </author>
    
    <category term="webscraper" label="Web::Scraper" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="wwwmechanize" label="WWW::Mechanize" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>仕事をしていると、荷物を宅配便で送る業務っていうのがあるんですけれども、宅配便業者さんに引き渡した後、ちゃんと届いたか確認したいってことありますよね。</p>
<p>というわけで、今回はPerlでクロネコヤマトの荷物照会のページをスクレイピングして、荷物の状況表示を回収するPerlスクリプトです。</p>
<p>応用すると、未配達の荷物を追跡して問い合わせるロボットなんかが作れるかもしれません。</p>
<p>今回は、モジュールにしてみましたので、ディレクトリをしっかり掘って使ってみてください。</p>
<p>Filename: WebService/KuronekoYamato.pm</p>
<pre class="prettyprint">
package WebService::KuronekoYamato;
 
use warnings;
use strict;
use Carp;
 
use version; our $VERSION = qv(&#39;0.0.1&#39;);
 
# Other recommended modules (uncomment to use):
#  use IO::Prompt;
#  use Perl6::Export;
#  use Perl6::Slurp;
#  use Perl6::Say;
use Encode;
use WWW::Mechanize;
use Web::Scraper;
use YAML::Syck;
 
 
# Module implementation here
 
# コンストラクタ
sub new {
  my ( $class ) = shift;
  my $mech = WWW::Mechanize-&gt;new();
  $mech-&gt;agent_alias( &#39;Windows IE 6&#39; );
  $mech-&gt;get(&#39;http://toi.kuronekoyamato.co.jp/cgi-bin/tneko?init&#39;);
  my $self = { mech =&gt; $mech, };
  bless $self;
}
 
# ヤマト運輸に問い合わせ
sub check {
  my $self    = shift;
  my $numbers = shift; # 荷物問い合わせ番号のリストのリファレンス
  # フォームの問い合わせは10件ごとなので10件ごとのリストのリストにする
  my $list; # 10件ごとに分割されたリストのリストが入る
  my $j = -1; #添え字調整
  foreach ( my $i = 0; $i &lt; $#$numbers + 1; $i++ ) {
    $j++ unless $i % 10;
    push @{$list-&gt;[$j]}, $numbers-&gt;[$i];
  }
  # _requestを呼んで実際にWebアクセスする
  my $result = [];
  foreach my $item( @$list ) {
    my $res = _request($self, $item);
    push @$result, @$res; # 返答は最大10件なので、$resultにためていく
  }
  return $result; # 集まったリストを返す
}
 
# 実際にリストからアクセスする
sub _request {
  my $self = shift;
  my $list = shift;
  $self-&gt;{mech}-&gt;form_number(1);
  for ( my $i = 0; $i &lt; $#$list + 1; $i++) {
    my $field = sprintf &quot;number%02d&quot;, $i+1;
    $self-&gt;{mech}-&gt;set_fields( $field =&gt; $list-&gt;[$i]);
  }
  $self-&gt;{mech}-&gt;submit;
  
  # Web::Scraper による解析
  my $s = scraper {
    process &#39;//tr/td[1]/input/../../td[2][contains(. , &quot;-&quot;)]/..&#39;,
    &#39;tneko[]&#39; =&gt; scraper {
      process &#39;//td[2]&#39;,
      number =&gt; &#39;TEXT&#39;,
      process &#39;//td[3]&#39;,
      date =&gt; &#39;TEXT&#39;,
      process &#39;//td[4]&#39;,
      status =&gt; &#39;TEXT&#39;,
    },
  };
  my $res = $s-&gt;scrape( # Shift_JISをUTF-8に変換
              encode(&#39;utf8&#39;, decode(&#39;cp932&#39;, $self-&gt;{mech}-&gt;content() ) )
            );
  # 得られた結果をリストで返す
  return $res-&gt;{tneko};
}
 
sub dump {
  my $self = shift;
  print Dump($self);
  return;
}
 
1; # Magic true value required at end of module
__END__</pre>

使うときは、

<pre class="prettyprint">
#!/usr/bin/perl
 
use lib qw(lib/);
package main;
use strict;
use warnings;
use YAML::Syck;
use WebService::KuronekoYamato;
use utf8;
 
 
my $n = WebService::KuronekoYamato-&gt;new();
my $res = $n-&gt;check([
  240000000000,
  240000000011,
]);
 
print Dump($res);
exit;</pre>

<p>こんな感じで使うといいんじゃないでしょうか。身の回りにあるクロネコヤマトの発送伝票で試してみてください。</p>
<p>ねえよ。</p>
<p>今回のは、CoreReposにも置いてあります。正直言ってPerlのモジュールやらオブジェクト指向がよくわかっていないっぽいので、修正してもらえればなあとも思ってたり。</p>
<p><a href="http://svn.coderepos.org/share/lang/perl/WebService-KuronekoYamato/">http://svn.coderepos.org/share/lang/perl/WebService-KuronekoYamato/</a></p>
<p>～～～</p>
<p>このようなスクリプトがあったところで、大事なのは、荷物が動いていなかったときの交渉と手配だったりすることは言うまでもありません。</p>
<p>今回のエントリは、<br />
<a href="http://blog.dtpwiki.jp/dtp/2007/08/user_scriptoper_7948.html">M.C.P.C.: クロネコヤマトの荷物お問い合わせシステムでテキストボックスへフォーカスを合わせるUser Script（Opera用）</a><br />
<a href="http://blog.dtpwiki.jp/dtp/2006/09/plagger_6158.html">M.C.P.C.: Plaggerでクロネコヤマトの荷物お問い合わせが出来ればいいよね</a><br />
あたりが元ネタです。</p>]]>
        
    </content>
</entry>

<entry>
    <title>perlはモジュール(cpan)がすてき！</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/09/perlcpan.html" />
    <id>tag:perl-mongers.org,2008://1.81</id>

    <published>2008-09-12T14:37:33Z</published>
    <updated>2008-09-12T15:08:12Z</updated>

    <summary>大阪から、こんばんはこんばんは！ perlはモジュールが素敵なんだよ。たぶん、あ...</summary>
    <author>
        <name>tomyhero [livedoor.com]</name>
        <uri>http://profile.livedoor.com/tomyhero/</uri>
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="lyricsfetcherlyricwiki" label="Lyrics::Fetcher::LyricWiki" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>大阪から、こんばんはこんばんは！</p>
<br />
<p>perlはモジュールが素敵なんだよ。たぶん、あなたの隣の席の、白い歯が似合うハンサムボーイより素敵だよ！</p>
<br />
<p>NIrvanaのRape Meの歌詞が見たい！とか急に思うよね。　思っちゃうよね。そういうときは、もちろんcpan 検索だね。</p>

<h4> モジュール探す</h4>

<p><a href="http://search.cpan.org/search?query=lyrics">http://search.cpan.org/search?query=lyrics</a></p>
<br />
<p>色々みつかったね！そのうちの一つをピックアップしたよ！</p>

<h4> モジュールインストール</h4>

<p>インストール！</p>
<pre>
sudo cpan install Lyrics::Fetcher::LyricWiki
</pre>

<h4> ソース</h4>

<p>歌詞をプリントアウトするよ</p>

<pre>
#!/usr/bin/perl

use strict;
use warnings;
use Lyrics::Fetcher::LyricWiki;
print Lyrics::Fetcher::LyricWiki-&gt;fetch(&#39;nirvana&#39; , &#39;rape me&#39;);
</pre>

<p>良い子のみんな、表示できたよね！　結果貼付けると、著作権的に怒られるかもしれないから、</p>
<p>自粛したよ。よくわかってないけどね！</p>

<h4> 最後に</h4>

<p>普通にgoogleで検索するより何か、ワクワクするでしょ。　こういった面白モジュールがたくさんみつかるのはperlが一番じゃないかな！　</p>
<br />
<p>ワクワクモジュールみつけたら、perl-mongers.orgに記事書くと良いと思うよ！</p>
<br />
<p>:wq!</p>




]]>
        
    </content>
</entry>

<entry>
    <title>Web::ScraperライクなテンプレートエンジンTemplate::Refine</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/09/template-refine.html" />
    <id>tag:perl-mongers.org,2008://1.80</id>

    <published>2008-09-11T13:06:19Z</published>
    <updated>2008-09-11T13:39:28Z</updated>

    <summary>Template::Refineというモジュールを見つけました。リンク先にある通...</summary>
    <author>
        <name>mattn.myopenid.com</name>
        <uri>http://mattn.kaoriya.net/</uri>
    </author>
    
    <category term="templaterefine" label="Template::Refine" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p><a href="http://blog.jrock.us/articles/Template%3A%3ARefine.pod">Template::Refine</a>というモジュールを見つけました。リンク先にある通り、ruleを使うことで簡単にテンプレートの値を置き換える事が出来ます。このモジュールの良い所は、テンプレートファイルにテンプレートエンジン専用の識別子を記述しなくて良い所。どうやって指定するかというと、XPathを使います。リンク先から引用すると</p>
<pre>
<span class="synStatement">my</span> <span class="synIdentifier">$username</span> = <span class="synConstant">&#39;Test User&#39;</span>;
<span class="synStatement">my</span> <span class="synIdentifier">$rule</span> = simple_replace {
    <span class="synStatement">my</span> <span class="synIdentifier">$node</span> = <span class="synStatement">shift</span>;
    <span class="synStatement">return</span> replace_text <span class="synIdentifier">$node</span>, <span class="synIdentifier">$username</span>;
} <span class="synConstant">&#39;//*[@class=&quot;username&quot;]&#39;</span>;
</pre>
<p>といった感じにルールを決め</p>
<pre>
<span class="synIdentifier">$frag</span> = <span class="synIdentifier">$frag</span>-&gt;process(<span class="synIdentifier">$rule</span>);
say <span class="synIdentifier">$frag</span>-&gt;render;
</pre>
<p>と実行する事でテンプレートへの反映が行われます。まるでWeb::Scraperの様ですね。</p>
<p>今日はサンプルとして、<a href="http://dzfl.jp/blog/2007/07/29/miwa-mojo-api/">美輪明宏のチンコの有無を返すAPI</a>から得た結果をテンプレートに反映してみたいと思います。</p>
<p>まずテンプレート</p>
<pre>
<span class="synIdentifier">&lt;</span><span class="synStatement">p</span><span class="synIdentifier">&gt;</span>美輪明宏にチンコは...<span class="synIdentifier">&lt;</span><span class="synStatement">span</span><span class="synIdentifier"> </span><span class="synType">class</span><span class="synIdentifier">=</span><span class="synConstant">&quot;miwa&quot;</span><span class="synIdentifier">&gt;</span>...<span class="synIdentifier">&lt;/</span><span class="synStatement">span</span><span class="synIdentifier">&gt;</span>。<span class="synIdentifier">&lt;/</span><span class="synStatement">p</span><span class="synIdentifier">&gt;</span>
</pre>
<p>確かにテンプレート専用の識別子は使用していません。そしてperlのコード</p>
<pre>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Encode;
<span class="synStatement">use </span>Perl6::Say;
<span class="synStatement">use </span>LWP::Simple;
<span class="synStatement">use </span>JSON;
<span class="synStatement">use </span>Template::Refine::Fragment;
<span class="synStatement">use </span>Template::Refine::Utils <span class="synConstant">qw(replace_text simple_replace)</span>;

<span class="synStatement">my</span> <span class="synIdentifier">$miwa</span> = from_json(get <span class="synConstant">&quot;http://dzfl.jp/mojo/&quot;</span>);
<span class="synStatement">my</span> <span class="synIdentifier">$rule</span> = simple_replace {
    <span class="synStatement">my</span> <span class="synIdentifier">$node</span> = <span class="synStatement">shift</span>;
	<span class="synStatement">return</span> replace_text <span class="synIdentifier">$node</span>, encode_utf8(<span class="synIdentifier">$miwa</span>-&gt;{miwa} ? <span class="synConstant">&#39;ある&#39;</span> : <span class="synConstant">&#39;ない&#39;</span>);
} <span class="synConstant">&#39;//*[@class=&quot;miwa&quot;]&#39;</span>;

<span class="synStatement">my</span> <span class="synIdentifier">$frag</span> = Template::Refine::Fragment-&gt;new_from_file(<span class="synConstant">&#39;template.html&#39;</span>);
<span class="synStatement">print</span> <span class="synIdentifier">$frag</span>-&gt;process(<span class="synIdentifier">$rule</span>)-&gt;render;
</pre>
<p>HTMLのmiwaというクラス属性を持ったノードに対して&quot;ある&quot;/&quot;ない&quot;というテキストで置換しています。</p>
<p>簡単ですね。テンプレートエンジン専用の識別子を使用しないので、HTMLの属性値さえ決めておけば、テンプレートの殆どをデザイナさんに任せてしまう事も出来る様になります。</p>
<p>すばらしいですね。</p>

]]>
        
    </content>
</entry>

<entry>
    <title>Getopt::Chainでgitライクなsubcommandを処理する</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/08/getoptchaingitsubcommand.html" />
    <id>tag:perl-mongers.org,2008://1.79</id>

    <published>2008-08-24T02:49:56Z</published>
    <updated>2008-08-24T13:04:15Z</updated>

    <summary>Yokohama.pmでxcezxさんがMonday Moduleのtech t...</summary>
    <author>
        <name>http://www.hatena.ne.jp/dann/</name>
        <uri>http://www.hatena.ne.jp/dann/</uri>
    </author>
    
    <category term="commandline" label="commandline" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="getoptchain" label="Getopt::Chain" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mondaymodule" label="monday-module" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>Yokohama.pmでxcezxさんがMonday Moduleのtech talkをされていたので、早速書いてみました。</p>
<p><a href="http://d.hatena.ne.jp/xcezx/">http://d.hatena.ne.jp/xcezx/</a></p>
<br />
<p>今回紹介するのは、gitのようなsubcommandのoptionを処理してくれるモジュールです。</p>
<p>gitだと、例えば以下のようにcommitサブコマンドにオプションを渡します。このオプションなどをパースしてくれて、簡単に取得できるようにしてくれます。</p>

<blockquote>
<p>  git.pl init --quiete</p>
<p>  git.pl commit -a -m &#39;Hello&#39;</p>
</blockquote>

<p>commands以下にsubcommandの記述を書くと、そのsubcommandのcontextで引数の値などを取得する事ができます。例えば、commitサブコマンドのmオプションの値とかが簡単にとれるようになります。</p>

<pre>
<span class="synPreProc">#!/usr/bin/env perl</span>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Getopt::Chain;
<span class="synStatement">use </span>Perl6::Say;

main();

<span class="synStatement">sub</span><span class="synIdentifier"> main </span>{
    setup_commands();
}

<span class="synStatement">sub</span><span class="synIdentifier"> setup_commands </span>{
    Getopt::Chain-&gt;process(
        <span class="synConstant">options </span>=&gt; [<span class="synConstant">qw/ version /</span>],
        <span class="synConstant">run </span>=&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
            <span class="synStatement">my</span> <span class="synIdentifier">$context</span>   = <span class="synStatement">shift</span>;
            <span class="synStatement">my</span> <span class="synIdentifier">@arguments</span> = <span class="synIdentifier">@_</span>;
            say <span class="synIdentifier">$context</span>-&gt;local_option(<span class="synConstant">&#39;version&#39;</span>);
        },

        <span class="synConstant">commands </span>=&gt; {
            <span class="synConstant">init </span>=&gt; {
                <span class="synConstant">options </span>=&gt; [<span class="synConstant">qw/ quiet|q template=s shared=s/</span>],
                <span class="synConstant">run     </span>=&gt; ¥<span class="synIdentifier">&amp;init</span>,
            },
            <span class="synConstant">commit </span>=&gt; {
                <span class="synConstant">options </span>=&gt; [<span class="synConstant">qw/ auto|a message|m=s /</span>],
                <span class="synConstant">run     </span>=&gt; ¥<span class="synIdentifier">&amp;commit</span>,
            },
        }
    );
}

<span class="synComment"># sub commands</span>
<span class="synStatement">sub</span><span class="synIdentifier"> init </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$context</span>   = <span class="synStatement">shift</span>;
    <span class="synStatement">my</span> <span class="synIdentifier">@arguments</span> = <span class="synIdentifier">@_</span>;

    <span class="synStatement">if</span>(<span class="synIdentifier">$context</span>-&gt;local_option(<span class="synConstant">&#39;quiet&#39;</span>)) {
        say <span class="synConstant">&#39;Only print error and warning messages.&#39;</span>;
    }
    say <span class="synIdentifier">$context</span>-&gt;local_option(<span class="synConstant">&#39;template&#39;</span>);
}

<span class="synStatement">sub</span><span class="synIdentifier"> commit </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$context</span>   = <span class="synStatement">shift</span>;
    <span class="synStatement">my</span> <span class="synIdentifier">@arguments</span> = <span class="synIdentifier">@_</span>;
    say <span class="synIdentifier">$context</span>-&gt;local_option(<span class="synConstant">&#39;message&#39;</span>);
}

<span class="synComment">__END__</span>
</pre>

]]>
        
    </content>
</entry>

<entry>
    <title>CatalystとConfig</title>
    <link rel="alternate" type="text/html" href="http://perl-mongers.org/2008/08/catalystconfig.html" />
    <id>tag:perl-mongers.org,2008://1.78</id>

    <published>2008-08-14T14:11:00Z</published>
    <updated>2008-08-14T14:29:47Z</updated>

    <summary>こんにちはこんにちは！ tomyheroです！　トミヘロじゃなくて、とぅーまいひ...</summary>
    <author>
        <name>tomyhero [livedoor.com]</name>
        <uri>http://profile.livedoor.com/tomyhero/</uri>
    </author>
    
    <category term="catalyst" label="Catalyst" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="configmulti" label="Config::Multi" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://perl-mongers.org/">
        <![CDATA[<p>こんにちはこんにちは！ tomyheroです！　トミヘロじゃなくて、とぅーまいひーろ　って読むんだよ！</p>
<br />
<p>今自分の中で流行ってる、CatalystとConfig周りの実装をこっそり晒そうと思うよ。　</p>

<h4> aim</h4>

<p>catalystアプリだけじゃなくて、外からでも使えるように実装したほうがいいとおもうんだよ！</p>

<h4> MyApp::Config</h4>

<p><a href="http://search.cpan.org/dist/Config-Multi/">Config::Multi</a>をシングルトンで、どこでもつかえるようにするよ。　 MyApp::Utils　というので、設定ファイルのパスをとってますね！これについては、後で書くよ！</p>

<pre>
<span class="synStatement">package</span><span class="synType"> MyApp::Config;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Config::Multi;
<span class="synStatement">use </span>MyApp::Utils;
<span class="synStatement">use base</span> <span class="synConstant">&#39;Class::Singleton&#39;</span>;

<span class="synStatement">our</span> <span class="synIdentifier">$FILES</span> ;
<span class="synStatement">sub</span><span class="synIdentifier"> _new_instance </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$cm</span> = Config::Multi-&gt;<span class="synStatement">new</span>(
        {
        <span class="synConstant">dir </span>=&gt; MyApp::Utils::path_to(<span class="synConstant">&#39;conf&#39;</span>)-&gt;stringify ,
        <span class="synConstant">app_name    </span>=&gt; <span class="synConstant">&#39;myapp&#39;</span> ,
        <span class="synConstant">extension   </span>=&gt; <span class="synConstant">&#39;yml&#39;</span>
    });
    <span class="synStatement">my</span> <span class="synIdentifier">$config</span> = <span class="synIdentifier">$cm</span>-&gt;load();
    <span class="synIdentifier">$FILES</span> = <span class="synIdentifier">$cm</span>-&gt;files;
    <span class="synStatement">return</span> <span class="synIdentifier">$config</span>;
}
<span class="synStatement">sub</span><span class="synIdentifier"> files </span>{
    <span class="synStatement">return</span> <span class="synIdentifier">$FILES</span>;
}

<span class="synConstant">1</span>;
</pre>

<h4> MyApp::Utils</h4>

<p>アプリケーションのUtilsモジュールだよ。Catalyst::Utilsだと、カタリスト依存しちゃうから、自分で作っちゃった方が良いと思うよ。 path_toとかのコードは、Catalystを参考にパクると良いと思うよ。</p>

<pre>
<span class="synStatement">package</span><span class="synType"> MyApp::Utils;</span>

<span class="synStatement">use warnings</span>;
<span class="synStatement">use strict</span>;
<span class="synStatement">use </span>Path::Class::Dir;
<span class="synStatement">use </span>Path::Class::File;
<span class="synStatement">use </span>FindBin;

<span class="synStatement">sub</span><span class="synIdentifier"> home </span>{
    <span class="synStatement">return</span> <span class="synIdentifier">$ENV</span>{MYAPP_HOME} ||  Path::Class::Dir-&gt;<span class="synStatement">new</span>(  <span class="synIdentifier">$FindBin::Bin</span>, <span class="synConstant">&#39;./../&#39;</span> );
}

<span class="synStatement">sub</span><span class="synIdentifier"> path_to </span>{
    <span class="synStatement">my</span> ( <span class="synIdentifier">@path</span> ) = <span class="synIdentifier">@_</span>;
    <span class="synStatement">my</span> <span class="synIdentifier">$path</span> = Path::Class::Dir-&gt;<span class="synStatement">new</span>( <span class="synIdentifier">&amp;home</span> , <span class="synIdentifier">@path</span> );
    <span class="synStatement">warn</span> <span class="synIdentifier">$path</span>;
    <span class="synStatement">if</span> ( <span class="synStatement">-d</span> <span class="synIdentifier">$path</span> ) { <span class="synStatement">return</span> <span class="synIdentifier">$path</span> }
    <span class="synStatement">else</span> { <span class="synStatement">return</span> Path::Class::File-&gt;<span class="synStatement">new</span>( <span class="synIdentifier">&amp;home</span>, <span class="synIdentifier">@path</span> ) }
}

<span class="synConstant">1</span>;
</pre>

<h4> MyApp::Plugin::Config</h4>

<p>オレオレコンフィグプラグインを作るよ！</p>
<p>ぶっちゃけ、MyApp::Config　を $c-&gt;config にぶっ込んでるだけだよ。</p>
<pre>
<span class="synStatement">package</span><span class="synType"> MyApp::Plugin::Config;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>MyApp::Config;
<span class="synStatement">use </span>NEXT;

<span class="synStatement">our</span> <span class="synIdentifier">$VERSION</span> =<span class="synConstant">&#39;0.02&#39;</span>;

<span class="synStatement">sub</span><span class="synIdentifier"> setup </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$c</span> = <span class="synStatement">shift</span>;
    <span class="synStatement">my</span> <span class="synIdentifier">$config</span> = MyApp::Config-&gt;instance();

    <span class="synStatement">if</span>( <span class="synIdentifier">$c</span>-&gt;debug ) {
        <span class="synStatement">my</span> <span class="synIdentifier">$files</span> = MyApp::Config-&gt;files();
        <span class="synStatement">for</span> <span class="synStatement">my</span> <span class="synIdentifier">$file</span> ( @{<span class="synIdentifier">$files</span>} ) {
            <span class="synIdentifier">$c</span>-&gt;<span class="synStatement">log</span>-&gt;debug( <span class="synConstant">&#39;Load Config &#39;</span> . <span class="synIdentifier">$file</span> );
        }
    }

    <span class="synIdentifier">$c</span>-&gt;config( <span class="synIdentifier">$config</span> ) ;
    <span class="synIdentifier">$c</span>-&gt;NEXT::setup( <span class="synIdentifier">@_</span> );
}

<span class="synConstant">1</span>;
</pre>

<h4>  MyApp::Web</h4>

<p>カタリストアプリだよ。プラグイン読み込むよ。</p>

<pre>
<span class="synStatement">package</span><span class="synType"> MyApp::Web;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Catalyst::Runtime <span class="synConstant">&#39;5.70&#39;</span>;
<span class="synStatement">use </span>Catalyst <span class="synConstant">qw/+MyApp::Plugin::Config/</span>;
<span class="synStatement">our</span> <span class="synIdentifier">$VERSION</span> = <span class="synConstant">&#39;0.01&#39;</span>;
__PACKAGE__-&gt;setup;

<span class="synConstant">1</span>;
</pre>

<h4>  conf/myapp_web.yml</h4>

<p>設定ファイルだよ。</p>

<pre>
---
name: Config Sample
</pre>

<h4> MyApp::Web::Controller::Root</h4>

<p>コンフィグデータが、ちゃんととれてるか表示するよ！</p>

<pre>
<span class="synStatement">package</span><span class="synType"> MyApp::Web::Controller::Root;</span>

<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use base</span> <span class="synConstant">&#39;Catalyst::Controller&#39;</span>;

__PACKAGE__-&gt;config-&gt;{namespace} = <span class="synConstant">&#39;&#39;</span>;

<span class="synStatement">sub</span><span class="synIdentifier"> default : Private </span>{
    <span class="synStatement">my</span> ( <span class="synIdentifier">$self</span>, <span class="synIdentifier">$c</span> ) = <span class="synIdentifier">@_</span>;
    <span class="synIdentifier">$c</span>-&gt;response-&gt;body(  <span class="synIdentifier">$c</span>-&gt;config-&gt;{name} );
}

<span class="synStatement">sub</span><span class="synIdentifier"> end : ActionClass(&#39;RenderView&#39;) </span>{}

<span class="synConstant">1</span>;
</pre>

<p>たぶんみえてるんじゃないかな！</p>

<h4> おわり</h4>

<p>以上だよ。　</p>
<p>ちなみに、 MyApp::Config はどこからでも呼べるから、ガンガン呼ぶと良いと思うよ。多い日も安心だね！</p>
<br />
<p>:wq!</p>

]]>
        
    </content>
</entry>

</feed>
