<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>log4ZIGOROu</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/" />
   <link rel="self" type="application/atom+xml" href="https://labs.cybozu.co.jp/blog/yamaguchi/atom.xml" />
   <id>tag:labs.cybozu.co.jp,2008:/blog/yamaguchi//14</id>
   <updated>2008-08-28T07:31:39Z</updated>
   <subtitle>History and memo in Cybozu labs.</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.33-ja</generator>

<entry>
   <title>Pathtraq API のページカウンタで複数のURLが指定出来るようになりました</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2008/08/pathtraq_api_url.html" />
   <id>tag:labs.cybozu.co.jp,2008:/blog/yamaguchi//14.2010</id>
   
   <published>2008-08-28T07:22:23Z</published>
   <updated>2008-08-28T07:31:39Z</updated>
   
   <summary> リリース以来、様々なサイトで使われているパストラックAPIですが、以前からリク...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Info" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="145" label="API" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="119" label="Pathtraq" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="120" label="パストラック" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
リリース以来、様々なサイトで使われている<a href="http://pathtraq.com/developer/">パストラックAPI</a>ですが、以前からリクエストのあった<a href="http://pathtraq.com/developer/#help_page_counter">ページカウンタAPI</a>にて複数のURLが指定出来るように致しました。
</p>]]>
      <![CDATA[<p>
これに伴い以前は <strong>http://api.pathtraq.com/page_counter</strong> がエンドポイントでしたが、以前の機能はそのまま残しつつ <strong>obsolete</strong> とし、<strong>http://api.pathtraq.com/page_counter2</strong> が新しいエンドポイントとなります。末尾に2がついただけです。
</p>
<p>
出力フォーマットも多少変わっておりますので、詳しくは<a href="http://pathtraq.com/developer/">開発者向け情報</a>をご覧下さい。
</p>]]>
   </content>
</entry>
<entry>
   <title>perlで気軽にsitemap.xmlを作る</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2008/02/perlsitemapxml.html" />
   <id>tag:labs.cybozu.co.jp,2008:/blog/yamaguchi//14.1771</id>
   
   <published>2008-02-07T06:00:24Z</published>
   <updated>2008-02-07T06:11:55Z</updated>
   
   <summary>perlでお手軽にsitemap.xmlを動的に作ってしまう話</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="118" label="perl seo" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
  <a href="http://www.sitemaps.org/protocol.php">sitemap.xml</a>とは、検索エンジンに対してクロールして欲しいURLを指定したり、その指定したURLの優先度を設定したりする事が出来るXML Formatの事です。<br />
　このXMLをサイト上に置いて、Google WebMaster Tool等で通知したり、robots.txtでSiteMapのLocationを指定する事によって、検索エンジンクローラが自動的にsitemap.xmlの場所を認識して、そのxmlファイルを参考にクロールしてくれるでしょう。
</p>
<p>
  今回はこのsitemap.xmlをperlで動的に書く方法です。
</p>]]>
      <![CDATA[<p>
  いきなりですが結論です。<br />
  <a href="http://search.cpan.org/dist/WWW-Google-SiteMap/">WWW::Google::SIteMap</a>モジュールを使いましょう。
</p>

<pre><code>
<span class="synPreProc">#!/usr/bin/perl</span>

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

<span class="synStatement">use </span>WWW::Google::SiteMap;
<span class="synStatement">use </span>WWW::Google::SiteMap::URL;

<span class="synStatement">my</span> <span class="synIdentifier">$map</span> = WWW::Google::SiteMap-&gt;<span class="synStatement">new</span>();

<span class="synIdentifier">$map</span>-&gt;add(WWW::Google::SiteMap::URL-&gt;<span class="synStatement">new</span>(
    <span class="synConstant">loc </span>=&gt; <span class="synConstant">'http://sample.com/'</span>,
    <span class="synConstant">priority </span>=&gt; <span class="synConstant">1.0</span>,
	<span class="synConstant">changefreq </span>=&gt; <span class="synConstant">'daily'</span>,
));

<span class="synStatement">print</span> <span class="synIdentifier">$map</span>-&gt;xml;
</code></pre>

<p>
こんな具合で簡単に出来てしまいます。例えばWebアプリケーションの場合だと複雑なクエリパラメータがついていたり、あるいはPATH_INFOをゴリゴリ弄ったりしてURL文字列を生成しているなんてケースもあるかと思いますので、WebアプリケーションでそのようなURL生成ルーチンがある場合は、動的に生成してしまった方が良いシーンもあるかと思います。
</p>

<p>
<a href="http://search.cpan.org/dist/WWW-Google-SiteMap/lib/WWW/Google/SiteMap/URL.pm">WWW::Google::SiteMap::URLモジュールのpod</a>に各url要素に指定出来る値に相当するアクセサがありますので、詳細はそちらの方でご確認下さい。(ちなみに最終更新日にDateTimeモジュールが使えるようになってます。)
</p>]]>
   </content>
</entry>
<entry>
   <title>XULでCanvasエディターを作ってみた</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/06/xulcanvas.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1318</id>
   
   <published>2007-06-04T10:47:38Z</published>
   <updated>2007-06-04T11:06:02Z</updated>
   
   <summary> 手軽にCanvasで遊べるツールとしてはオンラインにCanvas Shellと...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Mozilla" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="78" label="canvas" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="17" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="72" label="mozilla" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="79" label="xul" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
手軽にCanvasで遊べるツールとしてはオンラインに<a href="http://mozilla.doslash.org/stuff/canvas/shell.html">Canvas Shell</a>と言う物があります。
</p>
<p>
車輪の再発明感が多々ありますけど、Canvasで遊べるエディターを作ってみました。
</p>
<p>
タイトル通り激しくFirefox専用です。
</p>]]>
      <![CDATA[<div class="section">
  <h2>ダウンロード</h2>
  <p>
    <a href="https://labs.cybozu.co.jp/blog/yamaguchi/canvas.xul">Canvas Editor</a>
  </p>
</div>
<div class="section">
  <h2>使い方</h2>
  <p>
    デフォルトで、<var>canvas</var>, <var>ctx</var>がいきなり使えるようになってます。
  </p>
</div>
<div class="section">
  <h2>サンプル</h2>
  <p>貼付けてすぐに試せるサンプルです。</p>
  <div class="section">
    <h3>clip()の例</h3>
    <p>via <a href="http://developer.mozilla.org/ja/docs/Canvas_tutorial:Compositing">Canvas Tutorial : Compositing</a></p>
    <pre><code class="javascript">
function draw() {
  ctx.fillRect(0,0,150,150);
  ctx.translate(75,75);

  // Create a circular clipping path       
  ctx.beginPath();
  ctx.arc(0,0,60,0,Math.PI*2,true);
  ctx.clip();

  // draw background
  var lingrad = ctx.createLinearGradient(0,-75,0,75);
  lingrad.addColorStop(0, '#232256');
  lingrad.addColorStop(1, '#143778');
 
  ctx.fillStyle = lingrad;
  ctx.fillRect(-75,-75,150,150);

  // draw stars
  for (j=1;j<50;j++){
    ctx.save();
    ctx.fillStyle = '#fff';
    ctx.translate(75-Math.floor(Math.random()*150),75-Math.floor(Math.random()*150));
    drawStar(ctx,Math.floor(Math.random()*4)+2);
    ctx.restore();
  }
 
}
function drawStar(ctx,r){
  ctx.save();
  ctx.beginPath()
  ctx.moveTo(r,0);
  for (i=0;i<9;i++){
    ctx.rotate(Math.PI/5);
    if(i%2 == 0) {
      ctx.lineTo((r/0.525731)*0.200811,0);
    } else {
      ctx.lineTo(r,0);
    }
  }
  ctx.closePath();
  ctx.fill();
  ctx.restore();
}

draw();
</code></pre>
  </div>
  <div class="section">
    <h3>同心円状にグラデーション</h3>
    <pre><code class="javascript">
ctx.translate(75,75);
 
ctx.beginPath();
ctx.arc(0,0,60,0,Math.PI*2,true);
ctx.clip();

var lingrad = ctx.createRadialGradient(0, 0, 0, 0, 0, 75);
lingrad.addColorStop(0, '#838286');
lingrad.addColorStop(1, '#143778');

ctx.fillStyle = lingrad;
ctx.fillRect(-75,-75,150,150);
    </code></pre>
  </div>
</div>
<div class="section">
  <h2>合わせて読みたい！(追記)</h2>
  <p>
    なんだかAmazonのリコメンドっぽぃですが、
  </p>
  <ul>
    <li><a href="http://www.openspc2.org/HTML/appendix/canvas_param/index.html">&lt;canvas&gt;タグ リファレンス</a></li>
    <li><a href="http://developer.mozilla.org/en/docs/Category:HTML:Canvas">Category:HTML:Canvas</a></li>
  </ul>
  <p>辺りを読むとよりCanvasを楽しめるかもしれません。</p>
  <p>drawWindow()が使えないから、extensionにするかもです。</p>
</div>]]>
   </content>
</entry>
<entry>
   <title>nsIObserverServiceを使って複数のobserverに通知を行う</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/06/nsiobserverserviceobserver.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1313</id>
   
   <published>2007-06-01T08:29:44Z</published>
   <updated>2007-06-01T09:53:34Z</updated>
   
   <summary> FirefoxやThunderbirdの拡張を作る際に、場合によっては非同期処...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Extension" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="75" label="Extension" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="71" label="JavaScript" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="73" label="Mozilla" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="77" label="Observer" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
FirefoxやThunderbirdの拡張を作る際に、場合によっては非同期処理が入ったりします。
</p>
<p>
XPCOMではそのような場面でobserverが簡単に仕込める仕組みとして、<a href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIObserverService.html" title="nsIObserverService">nsIObserverService</a>と言うインターフェ−スがあるので、今回はその使い方についてご紹介します。
</p>]]>
      <![CDATA[<div class="section">
  <h2>ObserverServiceの概要</h2>
  <p>
    そもそも<a href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIObserverService.html" title="nsIObserverService">nsIObserverService</a>には下記のようなメソッドが定義されています。
  </p>
  <ul>
    <li>addObserver()</li>
    <li>removeObserver()</li>
    <li>notifyObservers()</li>
    <li>enumerateObservers()</li>
  </ul>
  <p>
    以下簡単にそれぞれについて触れてみます。
  </p>
  <dl>
    <dt>addObserver, removeObserver</dt>
    <dd>特定のtopicに対して通知を受け取るobserverオブジェクトを設定したり消したり出来ます。</dd>
    <dt>notifyObservers()</dt>
    <dd>特定のtopicを監視する全てのobserverに対して通知します</dd>
    <dt>enumerateObservers()</dt>
    <dd>特定のtopicを監視するobserverをenumerationとして取得します。</dd>
  </dl>
</div>
<div class="section">
  <h2>observerの作り方</h2>
  <p>
    <a href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIObserver.html" title="nsIObserver">nsIObserver</a>と言うインターフェースが存在しますので、その型を実装すれば問題無く使えます。
  </p>
  <pre><code class="javascript">
<span class="synType">var</span> testObserver = <span class="synIdentifier">{</span>
  observe: <span class="synIdentifier">function</span>(subject, topic, data) <span class="synIdentifier">{</span>
    <span class="synStatement">if</span> (topic != <span class="synConstant">&quot;testTopic&quot;</span>) <span class="synIdentifier">{</span>
      <span class="synStatement">return</span>;
    <span class="synIdentifier">}</span>

    repl.print((<span class="synError">{</span>
      <span class="synConstant">&quot;subject&quot;</span>: subject,
      <span class="synConstant">&quot;topic&quot;</span>: topic,
      <span class="synConstant">&quot;data&quot;</span>: data
    <span class="synError">}</span>).toSource());
  <span class="synIdentifier">}</span>
<span class="synIdentifier">}</span>;</code></pre>
  <p>
    と言う訳でobserveメソッドを持つ適当なオブジェクトを上記のように作れば、後はnotifyがあればその通知を受け取る事が出来ます。
  </p>
  <p>
    ちなみにMozRepl経由で確認すると楽に出来ます。<br />
    他の方法で見る方はalertなりerror consoleなりお好きな所に出力して下さい。
  </p>
</div>
<div class="section">
  <h2>observerの登録</h2>
  <p>
    windowのload, unloadイベントでaddObserver(), removeObserver()を呼び出す処理を追記したobserverだと下記のようになります。
  </p>
  <pre><code class="javascript">
<span class="synType">var</span> testObserver = <span class="synIdentifier">{</span>
  observerService: null,
  init: <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span>
    testObserver.observerService = Components.classes[<span class="synConstant">&quot;@mozilla.org/observer-service;1&quot;</span>]
      .getService(Components.interfaces.nsIObserverService);
    testObserver.observerService.addObserver(testObserver, <span class="synConstant">&quot;testTopic&quot;</span>, <span class="synConstant">false</span>);
  <span class="synIdentifier">}</span>,
  observe: <span class="synIdentifier">function</span>(subject, topic, data) <span class="synIdentifier">{</span>
    <span class="synStatement">if</span> (topic != <span class="synConstant">&quot;testTopic&quot;</span>) <span class="synIdentifier">{</span>
      <span class="synStatement">return</span>;
    <span class="synIdentifier">}</span>

    repl.print((<span class="synError">{</span>
      <span class="synConstant">&quot;subject&quot;</span>: subject,
      <span class="synConstant">&quot;topic&quot;</span>: topic,
      <span class="synConstant">&quot;data&quot;</span>: data
    <span class="synError">}</span>).toSource());
  <span class="synIdentifier">}</span>,
  complete: <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span>
    testObserver.observerService.removeObserver(testObserver, <span class="synConstant">&quot;testTopic&quot;</span>);
  <span class="synIdentifier">}</span>
<span class="synIdentifier">}</span>;</code></pre>
  <p>
    testObserver.init, testObserver.completeは適当な場所で呼び出すようにしておきます。(例えばload, unloadイベントにaddEventListenerとして)
  </p>
</div>
<div class="section">
  <h2>observalな処理の中でnotifyObserversを使う</h2>
  <p>
    例えばですが、長く掛かる処理と言うのをsetTimeoutで表現したとして、
  </p>
  <pre><code class="javascript">
<span class="synType">var</span> TestObserval = <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span>
  <span class="synType">this</span>.observerService = Components.classes[<span class="synConstant">&quot;@mozilla.org/observer-service;1&quot;</span>]
    .getService(Components.interfaces.nsIObserverService);
<span class="synIdentifier">}</span>

TestObserval.prototype = <span class="synIdentifier">{</span>
  observerService: null,
  start: <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span>
    <span class="synType">this</span>.observerService.notifyObservers(null, <span class="synConstant">&quot;testTopic&quot;</span>, <span class="synConstant">&quot;start&quot;</span>);
    setTimeout(<span class="synType">this</span>.process, 3000);
  <span class="synIdentifier">}</span>,
  process: <span class="synIdentifier">function</span>() <span class="synIdentifier">{</span>
    <span class="synType">this</span>.observerService.notifyObservers(null, <span class="synConstant">&quot;testTopic&quot;</span>, <span class="synConstant">&quot;end&quot;</span>);
  <span class="synIdentifier">}</span>
<span class="synIdentifier">}</span>    
</code></pre>
  <p>
    としてあげて、オブジェクトを生成してstart()を実行してあげると、実際にnotifyが届いている事が分かると思います。
  </p>
</div>]]>
   </content>
</entry>
<entry>
   <title>CGI::Application::Plugin::Cache::Adaptive Release</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/05/cgiapplicationplugincacheadapt.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1291</id>
   
   <published>2007-05-22T03:17:12Z</published>
   <updated>2007-05-22T04:06:55Z</updated>
   
   <summary>   先日、奥さんの要望によりCache::AdaptiveをCGI::Appl...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
  先日、奥さんの要望により<a href="http://search.cpan.org/dist/Cache-Adaptive/lib/Cache/Adaptive.pm" title="Cache::Adaptive">Cache::Adaptive</a>を<a href="http://search.cpan.org/dist/CGI-Application/lib/CGI/Application.pm" title="CGI::Application">CGI::Application</a>で使いやすくするプラグインを書きました。<br />
  現在はversion 0.03でCPANに<a href="http://search.cpan.org/dist/CGI-Application-Plugin-Cache-Adaptive/lib/CGI/Application/Plugin/Cache/Adaptive.pm" title="CGI::Application::Plugin::Cache::Adaptive">CGI::Application::Plugin::Cache::Adaptive</a>としてアップされています。
</p>
<p>
  <a href="http://search.cpan.org/dist/Cache-Adaptive/lib/Cache/Adaptive.pm" title="Cache::Adaptive">Cache::Adaptive</a>自体については、CPANのドキュメントないしは、奥さんの下記の関連エントリをご覧下さい。
</p>
<ul>
  <li><a href="https://labs.cybozu.co.jp/blog/kazuho/archives/2007/05/cache_adaptive.php">負荷に応じてキャッシュを自動調節する Perl モジュール</a></li>
  <li><a href="https://labs.cybozu.co.jp/blog/kazuho/archives/2007/05/cache-adaptive_on_cpan.php">Cache::Adaptive の使い方</a></li>
  <li><a href="https://labs.cybozu.co.jp/blog/kazuho/archives/2007/05/cache-adaptive-0521.php">Cache::Adaptiveを簡単に使う方法</a></li>
</ul>
<p>
  使い方や実装方法について簡単に説明してみようと思います。
</p>]]>
      <![CDATA[<div class="section">
  <h3>すぐ分かる使い方</h3>
  <p>
    実際はやる事は二つしかありません。
  </p>
  <ul>
    <li><a href="http://search.cpan.org/dist/CGI-Application/lib/CGI/Application.pm" title="CGI::Application">CGI::Application</a>を継承したクラス内でcache_adaptive()メソッドを使って<a href="http://search.cpan.org/dist/Cache-Adaptive/lib/Cache/Adaptive.pm" title="Cache::Adaptive">Cache::Adaptive</a>または、派生クラス(<ins>例えば</ins><a href="http://search.cpan.org/dist/Cache-Adaptive-ByLoad/lib/Cache/Adaptive/ByLoad.pm">Cache::Adaptive::ByLoad</a>)のインスタンスを突っ込みます。</li>
    <li><a href="http://search.cpan.org/dist/CGI-Application/lib/CGI/Application.pm" title="CGI::Application">CGI::Application</a>を継承したクラス内でCacheさせたいメソッドにcode attributeとして、Cacheableを指定します。</li>
  </ul>
  <p>
    この二つに関して書いて行きます。
  </p>
</div>
<div class="section">
  <h3>cache_adaptive()による準備</h3>
<pre><code class="perl">
<span class="synStatement">sub</span><span class="synIdentifier"> setup </span>{
    <span class="synStatement">my</span> <span class="synIdentifier">$self</span> = <span class="synStatement">shift</span>;

    <span class="synComment">### snip</span>

    <span class="synIdentifier">$self</span>-&gt;cache_adaptive({
        <span class="synConstant">backend </span>=&gt; Cache::FileCache-&gt;<span class="synStatement">new</span>({
            <span class="synConstant">namespace </span>=&gt; <span class="synConstant">'html_cache'</span>,
            <span class="synConstant">max_size  </span>=&gt; <span class="synConstant">10</span> * <span class="synConstant">1024</span> * <span class="synConstant">1024</span>,
        }),
        <span class="synConstant">expires_min </span>=&gt; <span class="synConstant">3</span>,
        <span class="synConstant">expires_max </span>=&gt; <span class="synConstant">60</span>,
        <span class="synConstant">check_load  </span>=&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
            <span class="synStatement">my</span> <span class="synIdentifier">$entry</span> = <span class="synStatement">shift</span>;
            <span class="synStatement">int</span>(<span class="synIdentifier">$entry</span>-&gt;{process_time} * <span class="synConstant">2</span>) - <span class="synConstant">1</span>;
        },
    });
}</code></pre>
  <p>基本、こんな感じで初期化するのですが、別のprofileを登録しておく事が出来ます。</p>
  <pre><code class="perl"><span class="synIdentifier">$self</span>-&gt;cache_adaptive(<span class="synConstant">'another_profile'</span>, <span class="synIdentifier">$cache_adaptive</span>);</code></pre>
  <p>
    これは後でprofileの選択が出来ると言う事です。
  </p>
</div>
<div class="session">
  <h3>Cacheable code attribute</h3>
  <p>
    内部的にはソースを見て頂ければ分かる通り、<a href="http://search.cpan.org/dist/Attribute-Handlers/lib/Attribute/Handlers.pm">Attribute::Handlers</a>を使っています。<br />
    このモジュールを使うと比較的簡単にattributeによる拡張が出来ます。
  </p>
  <p>
    Cacheable attributeで指定出来るkey_fromパラメータですが、下記の値を設定出来ます。
  </p>
  <ul>
    <li>path</li>
    <li>query</li>
    <li>path_info</li>
    <li>session</li>
  </ul>
  <p>
    特に今回はsessionと言う指定もあるように、session_idによって異なる結果が返って来るようなケースでも期待通りsession_idごとにキャッシュが適用出来るようにしました。
  </p>
  <pre><code class="perl">
<span class="synStatement">sub</span><span class="synIdentifier"> do_user_page : Cacheable(qw/path path_info session/) </span>{
    <span class="synComment">### process per user</span>
} </code></pre>
  <p>
    ちなみに指定があるkeyの種(path, query, path_info, session)とそれらの実際の値をHASHREF化して、Storableのfreeze使ってシリアライズした物をkeyとしているので、これらの値を組み合わせてユニークな値であればCache時のkeyもユニークになります。
  </p>
</div>
<div class="section">
  <h3>雑多なtips/BK</h3>
  <p>
    作ってる最中に幾つか覚えた事とかハマった事などです。
  </p>
  <dl>
    <dt>mod_perlとINIT, CHECK</dt>
    <dd>
      mod_perl化だとINIT, CHECKフェーズが存在しないようです。(少なくともAttribute::Handlersの指定はスルーされてます。)
      従って事実上、BEGINフェーズに引っ掛けるしかありません。
    </dd>
    <dt>CGI::Applicationのリアルなテスト</dt>
    <dd>
      <a href="http://search.cpan.org/dist/Test-WWW-Mechanize-CGI">Test::WWW::Mechanize::CGI</a>を使いましょう。
      ほとんど実際に動かしているのと同じようなテストが出来ます。<var>$ENV{CGI_APP_RETURN_ONLY}</var>によるテストは小学生まで。<br />
      当然、CGI::Applicationだけでなく、cgiとして動作させる物ならばなんでも適用可能です。
    </dd>
    <dt>安易なシンボルテーブル操作はミスの元w</dt>
    <dd>
      と言うか元々シンボルテーブルにアクセスして、書き換えてみたり、そのコードリファレンスを取得してゴニョゴニョしたりってのはフレームワーク側でしっかりと枠組みが無いと危険だなぁと。(Catalystと比較)<br />
      CGI::Applicationに関しては<a href="http://search.cpan.org/dist/CGI-Application/lib/CGI/Application.pm#Writing_Plug-ins" title="Writing Plug-ins">pluginによる拡張の規定が緩い</a>ので、みんな好き勝手書けてしまうのが今回は苦戦の元でした。<br />
      特に今回のようにattributeを使う場合、基本BEGINフェーズでattributeのparseが走って、その後に事前に拡張を仕込むような実装になるのですが、さらに元のCODEREFをwrapするなんて処理が入ると、<a href="http://search.cpan.org/dist/CGI-Application-Plugin-AutoRunmode" title="CGI::Application::Plugin::AutoRunmode">別にそのCODEREFを利用するようなモジュールがある</a>と凄い大変な事になります。
    </dd>
  </dl>
  <p>
    まぁとは言え、CGI::Applicationって実にシンプルだなぁと改めて思いました。<br />
    ちょっとしたアプリケーション作るのにCatalystをわざわざ使う必要性は全然無くて、適材適所で判断出来ればいいのかなぁと思います。
  </p>
</div>]]>
   </content>
</entry>
<entry>
   <title>Gearmanを使ってみた</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/04/gearman.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1232</id>
   
   <published>2007-04-24T04:03:29Z</published>
   <updated>2007-05-01T03:00:33Z</updated>
   
   <summary>   YAPC Asia 2007でも紹介されていたGearmanと言うjob ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="CPAN" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="4" label="CPAN" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="54" label="Gearman" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="56" label="PPerl" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="8" label="Perl" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
  <a href="http://tokyo2007.yapcasia.org/blog/ja/">YAPC Asia 2007</a>でも<a href="http://tokyo2007.yapcasia.org/sessions/2007/02/tbd.html" title="Behind the Scenes at LiveJournal: Scaling Storytime">紹介されて</a>いた<a href="http://www.danga.com/gearman/">Gearman</a>と言うjob serverを使ってみました。
</p>]]>
      <![CDATA[<div class="section">
  <h3>追記(2007-05-01)</h3>
  <ul>
    <li>gearmandをgearmanとしていたので修正</li>
    <li>$worker->work while 1; が抜けていたので追加(thanks id:tokuhirom)</li>
    <li>pperlでの検証結果を最後に触れておきました。</li>
  </ul>
</div>
<div class="section">
  <h3>インストール</h3>
  <p><a href="http://search.cpan.org/dist/gearmand/">gearmand</a>, <a href="http://search.cpan.org/dist/Gearman/">Gearman</a>をそれぞれCPANから入れるだけです。</p>
</div>
<div class="section">
  <h3>daemonの起動</h3>
  <p>下記のようにdaemonとして起動します。</p>
  <p>daemon起動オプションに関してですが、<a href="http://search.cpan.org/dist/gearmand/gearmand#OPTIONS" title="gearmandのコマンドオプション">PODの記載</a>は誤りで<strong>--daemonize</strong>では無く<strong>--daemon</strong>です。</p>
  <pre><code>$  sudo gearmand --daemon --pidfile=/var/log/gearmand.pid --debug=1
</code></pre>
</div>
<div class="section">
  <h3>関数の登録</h3>
  <p>
    次にgearmanに実行させたい処理を予め登録し、さらにjob queを待ち受けるworkerを記述します。
  </p>
  <pre><code><span class="synPreProc">#!/usr/bin/perl</span>

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

<span class="synPreProc">use </span>Data::Dump <span class="synConstant">qw(dump)</span>;
<span class="synPreProc">use </span>Gearman::Worker;
<span class="synPreProc">use </span>Storable <span class="synConstant">qw(thaw)</span>;
<span class="synPreProc">use </span>List::Util <span class="synConstant">qw(sum)</span>;

<span class="synStatement">my</span> <span class="synIdentifier">$worker</span> = Gearman::Worker-&gt;<span class="synStatement">new</span>;
<span class="synIdentifier">$worker-&gt;job_servers</span>(<span class="synConstant">qw|localhost|</span>);
<span class="synIdentifier">$worker-&gt;register_function</span>(
    <span class="synConstant">sum </span>=&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{
        <span class="synStatement">my</span> <span class="synIdentifier">$job</span> = <span class="synStatement">shift</span>;
        <span class="synStatement">my</span> <span class="synIdentifier">@args</span> = <span class="synIdentifier">@{</span>thaw(<span class="synIdentifier">$job-&gt;arg</span>)<span class="synIdentifier">}</span>;

        <span class="synStatement">return</span> sum <span class="synIdentifier">@args</span>;
    }
);
<span class="synIdentifier">$worker-&gt;work</span> <span class="synStatement">while</span> <span class="synConstant">1</span>;
</code></pre>
  <p>task_sum.plなどとして保存して実行します。</p>
  <p>注意する所としては下記のような所でしょうか。</p>
  <ul>
    <li>登録した関数に渡される第1引数はGearman::Jobオブジェクト</li>
    <li>argはtaskから渡されたSCALAR化した引数、argrefはそのリファレンス</li>
    <li>networkをまたがるのでStorableのようなシリアライザーが必須(無いと不便過ぎ。)</li>
  </ul>
  <p>func_sum.plなど適当なファイル名で保存し、実行しておきます。</p>
</div>
<div class="section">
  <h3>Execute Task</h3>
  <p>登録したsumを実際に実行する例です。</p>
  <pre><code>
<span class="synPreProc">#!/usr/bin/perl</span>

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

<span class="synPreProc">use </span>Data::Dump <span class="synConstant">qw(dump)</span>;
<span class="synPreProc">use </span>Storable <span class="synConstant">qw(freeze thaw)</span>;
<span class="synPreProc">use </span>Gearman::Client;
<span class="synPreProc">use </span>Gearman::Task;

<span class="synStatement">my</span> <span class="synIdentifier">$client</span> = Gearman::Client-&gt;<span class="synStatement">new</span>;
<span class="synIdentifier">$client-&gt;job_servers</span>(<span class="synConstant">qw|localhost|</span>);

<span class="synStatement">my</span> <span class="synIdentifier">$args</span> = freeze([<span class="synConstant">1.</span>.<span class="synConstant">9</span>]);

<span class="synStatement">my</span> <span class="synIdentifier">$result_ref</span> = <span class="synIdentifier">$client-&gt;do_task</span>(<span class="synConstant">&quot;sum&quot;</span>, <span class="synIdentifier">\$args</span>, {
});
<span class="synStatement">print</span> <span class="synIdentifier">$$result_ref</span>;
</code></pre>
  <p>45と表示されれば成功です。</p>
  <p>
    注意する点は単純なスカラー以外を渡す際は、いったんそのリファレンス(配列、ハッシュ、追いブジェクトなどなど)を一度Storableのfleezeにかましてスカラー化した物をリファレンスとして渡すと関数に対して事実上なんでも渡せる事になります。<br />
    この辺りがドキュメントが乏しいので分かりづらかったです。
  </p>
</div>
<div class="section">
  <h3>まとめ</h3>
  <p>実際動かしてみた時の疑問点、TODOです。</p>
  <ul>
    <li><del>register_functionは<a href="http://search.cpan.org/dist/PPerl/">PPerl</a>などで永続化しておくと良いかも。まだ未検証。</del><ins>検証しました。pperl使う意味は元々無いですし、実際ベンチ取ったらpperlの方が遅いです。</ins></li>
    <li>分散環境でどう動くかまだソース読んでないので分からない。register_functionは実際にtaskを処理するサーバー全部でやるんだろうか。</li>
    <li>ハンドラ(on_complete, on_fail)はまだ試してない</li>
    <li>background動作もまだ未検証</li>
  </ul>
  <p>実際のプロジェクトに組み込むにはノウハウがまだ自分に足りてないなと思いました。とは言え面白いプロダクトだと思います。</p>
</div>]]>
   </content>
</entry>
<entry>
   <title>「正しくHTMLを書こうと心がけている人に5つの質問」の回答</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/04/html5.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1213</id>
   
   <published>2007-04-17T02:03:06Z</published>
   <updated>2007-04-18T02:32:30Z</updated>
   
   <summary>   正しくHTMLを書こうと心がけている人に5つの質問と言うエントリがあって、...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="HTML/XHTML" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="50" label="DTD" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="46" label="HTML" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="48" label="XHTML" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
  <a href="http://www.rusica.net/note/2007/04/09/html5.html">正しくHTMLを書こうと心がけている人に5つの質問</a>と言うエントリがあって、<a href="http://purpr.in/blog/">purprinさん</a>の所で<a href="http://purpr.in/blog/log/07/04/17/0040">紹介</a>されていたので、私も回答してみようかと思います。
</p>]]>
      <![CDATA[<div class="section">
  <h3>HTML文書を制作する際に使用しているプログラムをお答えください。（Webプログラムも含む）</h3>
  <ul>
    <li>Emacs</li>
    <li>W3Cのvalidater</li>
    <li>稀にxmllint</li>
  </ul>
  <p>
    昔はhtml-helper-modeを使ってましたが今はnxhtml-modeを使ってます。<br />
    そのうちお手製の○○的なモジュールとコマンドとか作ろうかなとか画策してます。
  </p>
</div>
<div class="section">
  <h3>採用しているDTDとその理由をお答えください。</h3>
  <p>1.1にStrictなんて無いので、修正しました。(via <a href="http://b.hatena.ne.jp/entry/http%3A//labs.cybozu.co.jp/blog/yamaguchi/2007/04/html5.html">はてブ</a>)</p>
  <ul>
    <li>XHTML1.0 Strict</li>
    <li>XHTML1.1<del date="2007-04-18T11:11:30+09:00" title="1.1にStrictなんて無いですね、コピペミスしましたw" cite="http://b.hatena.ne.jp/entry/http%3A//labs.cybozu.co.jp/blog/yamaguchi/2007/04/html5.html"> Strict</del></li>
  </ul>
  <p>
    昔は1.0 Transitionalも使ってましたが、今は全然使わなくりました。Strictの文法は個人的には好きだし、理に適ってると思うので採用しています。<br />
    またStrictで非推奨扱いの物は個人的にもそうあるべきと同意出来る物が多いので、選んだ理由にもなります。
  </p>
  <p>
    これから書くなら1.1 Strictで書くと思います。
  </p>
</div>
<div class="section">
  <h3>何故正しくHTMLを書いているのですか？</h3>
  <ul>
    <li>そこに明確なシンタックスが存在するから</li>
    <li>parseしたりとかJavaScript書く上で正しく無いHTMLは扱いづらい事が多い（得てして汚いHTML）</li>
    <li>シンプルに記述する事によって可能な限り文書構造が正規化されたデータ構造くらいに扱えると嬉しい</li>
  </ul>
</div>
<div class="section">
  <h3>W3CとWHATWG、どちらに期待してますか？</h3>
  <p>
    いずれの団体にも期待していますけど、仕様がぐちゃぐちゃになったり、実装がまちまちにならないよう協調してくれる事だけは切に願います。
  </p>
</div>
<div class="section">
  <h3>あなたにとってHTMLとは何ですか？</h3>
  <p>
    色々思う事はあるのですが、箇条書きで特に最近思う事など書いてみます。
  </p>
  <ul>
    <li>HTML/XHTMLの内容を<strong>文書構造</strong>と呼ぶ辺りでWeb Applicationのインターフェース記述言語として既に限界がある気がしてます。前までは不思議にも思わなかったのに。</li>
    <li>文書を表す記述言語としてはシンプルで使いやすい物の、圧倒的に例えばDocBookなどと比べると語彙が少なすぎる。もう少しバリエーションが無いとclassとかclassとかcla(ry</li>
    <li>XHTML2.0は期待しています。</li>
    <li>とは言えここまでJavaScriptが流行ってる理由の一つにそれがブラウザですぐ試せるからと言う事が挙げられるのと同様に、HTML/XHTMLもすぐ試してブラウザで見れると言うシンプルさは非常に気に入ってます。</li>
  </ul>
  <p>
    まとめるとシンプルだけど奥深い、キャンバスみたいな物ですかね。
  </p>
</div>
]]>
   </content>
</entry>
<entry>
   <title>Modules in Games-Nintendo-Wii-Mii</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/04/modules_in_gamesnintendowiimii.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1208</id>
   
   <published>2007-04-16T02:26:51Z</published>
   <updated>2007-04-16T02:50:08Z</updated>
   
   <summary> 先週ですが、Games-Nintendo-Wii-Miiと言うモジュールをCP...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="CPAN" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="4" label="CPAN" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="40" label="Hash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="8" label="Perl" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="38" label="Tie" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="34" label="XML" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="36" label="XPath" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
先週ですが、<a href="http://search.cpan.org/dist/Games-Nintendo-Wii-Mii/">Games-Nintendo-Wii-Mii</a>と言うモジュールをCPANにリリースしました。
</p>
<p>
モジュールの事などつらつらと書いてみます。
</p>]]>
      <![CDATA[<div class="section">
    <h3><a href="http://search.cpan.org/dist/Tie-IxHash/lib/Tie/IxHash.pm">Tie::IxHash</a></h3>
    <p>
      順番を保持したいハッシュを実現したい場合に便利です。但し当然ですが余り速く無いのと、データも余計に消費しますので、濫用は避けるべきです。
    </p>
    <pre><code class="perl">
<span class="synPreProc">#!/usr/bin/perl</span>

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

<span class="synPreProc">use </span>Data::Dump <span class="synConstant">qw(dump)</span>;
<span class="synPreProc">use </span>Tie::IxHash;

<span class="synStatement">my</span> <span class="synIdentifier">%foo</span> = (<span class="synConstant">a </span>=&gt; <span class="synConstant">1</span>, <span class="synConstant">b </span>=&gt; <span class="synConstant">2</span>, <span class="synConstant">c </span>=&gt; <span class="synConstant">3</span>, <span class="synConstant">d </span>=&gt; <span class="synConstant">4</span>, <span class="synConstant">e </span>=&gt; <span class="synConstant">5</span>);

<span class="synStatement">print</span> <span class="synStatement">dump</span> <span class="synIdentifier">%foo</span>;

<span class="synStatement">tie</span>(<span class="synStatement">my</span> <span class="synIdentifier">%bar</span>, <span class="synConstant">'Tie::IxHash'</span>);

<span class="synIdentifier">%bar</span> = (<span class="synConstant">a </span>=&gt; <span class="synConstant">1</span>, <span class="synConstant">b </span>=&gt; <span class="synConstant">2</span>, <span class="synConstant">c </span>=&gt; <span class="synConstant">3</span>, <span class="synConstant">d </span>=&gt; <span class="synConstant">4</span>, <span class="synConstant">e </span>=&gt; <span class="synConstant">5</span>);

<span class="synStatement">print</span> <span class="synStatement">dump</span> <span class="synIdentifier">%bar</span>;</code></pre>
  <p>これで挙動の違いは抑えられるでしょう。</p>
</div>
<div class="section">
  <h3><a href="http://search.cpan.org/dist/XML-LibXML/lib/XML/LibXML/XPathContext.pod">XML::LibXML::XPathContext</a></h3>
  <p>
    XML-LibXMLは1.61から<a href="http://search.cpan.org/dist/XML-LibXML/lib/XML/LibXML/XPathContext.pod">XML::LibXML::XPathContext</a>が使用出来ます。特定のノード以下でXPath式のマッチテストやら、値の取り出しが非常にスムーズに出来ます。XPathは本当に便利ですねぇ。
  </p>
</div>]]>
   </content>
</entry>
<entry>
   <title>Module-Starterのカスタマイズ</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/04/modulestarter.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1179</id>
   
   <published>2007-04-02T05:05:29Z</published>
   <updated>2007-04-03T05:13:35Z</updated>
   
   <summary> いずれ奇麗にまとめてやろうと思ってたんですが、いい機会なのでこの辺りでmodu...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="CPAN" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="20" label="CPAN Perl Customize" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
いずれ奇麗にまとめてやろうと思ってたんですが、いい機会なのでこの辺りでmodule-starterの詳細とカスタマイズについて書いてみます。
</p>
<p>
ところで以前<a href="http://d.hatena.ne.jp/ZIGOROu/20061010/1160495430" title="Module::Starterのplugin機構が面白い件について">Module::Starterのplugin機構が面白い件について</a>と言うエントリを書いた事があるのですが、こちらに関して頭に入っているとより理解しやすいかもしれません。
</p>]]>
      <![CDATA[<div class="section">
  <h2>用途別のカスタマイズ</h2>
  <div class="section">
    <h3>名前とメールアドレスの設定</h3>
    <p>
      毎回author, emailを指定するのも面倒なので下記のように設定してしまいましょう。
      ~/.module-starter/configに記載します。
    </p>
    <pre>
author: Toru Yamaguchi
email: foo@example.com
    </pre>
    <p>
      これで次回からこのパラメータを指定する必要は無くなります。
    </p>
  </div>
  <div class="section">
    <h3>新しいモジュールを追加する</h3>
    <p>
      デフォルトのmodule-starterコマンドでは新しいモジュールを追加する事が出来ません。
    </p>
    <pre>$ module-starter --module=Foo
Created starter directories and files
$ module-starter --module=Foo::Bar --distro=Foo
Foo already exists.  Use --force if you want to stomp on it.</pre>
    <p>
      無理にforceオプションをつけて実行しても追加にはならず、直前に作ったFoo.pmが消えてFoo/Bar.pmで作り直したと言う扱いになってしまいます。
    </p>
    <p>
      これを解決するのがModule-Starter-Smartです。<br />
      このモジュールをインストールした後に ~/.module-starter/config ファイルに下記のように記述します。
    </p>
    <pre>plugins: Module::Starter::Simple Module::Starter::Smart</pre>
    <p>
      ちなみにModule::Starter::Smartのドキュメント中では説明が二カ所間違ってます。
    </p>
    <ol>
      <li>configの中でのプラグイン指定はpluginでは無くplugin<em>s</em></li>
      <li>追加の際にはauthorの指定は必要なのでSYNOPSYSにあるadd a new moduleで書かれているサンプルはそのままじゃ動かない</li>
    </ol>
    <p>
      これでとりあえずモジュールの追加は出来ました。
    </p>
  </div>
  <div class="section">
    <h3>テンプレートを使う</h3>
    <p>
      <a href="http://search.cpan.org/dist/Module-Starter/">Module-Starter</a>には元々<a href="http://search.cpan.org/dist/Module-Starter/lib/Module/Starter/Plugin/Template.pm" >Module::Starter::Plugin::Template</a>モジュールが含まれていますが、これ自体はインターフェースに過ぎず、implementしたモジュールが無いと使えません。
    </p>
    <ol>
      <li><a href="http://search.cpan.org/dist/Module-Starter-Plugin-TT2/">Module-Starter-Plugin-TT2</a></li>
      <li><a href="http://search.cpan.org/dist/Module-Starter-Plugin-Template-TeTe/">Module-Starter-Plugin-Template-TeTe</a></li>
    </ol>
    <p>
      が今の所の実装モジュールですが、皆使い慣れているであろうTT2の方を使ってみようと思います。
    </p>
    <p>
      ところで先にModule::Starter::Plugin::Templateですが、二つのメソッドをimplementsする必要があります。
    </p>
    <ul>
      <li>templates()</li>
      <li>rederer()</li>
    </ul>
    <p>
      でModule::Starter::Plugin::TT2, Module::Starter::Plugin::Template::TeTe共にrendererを提供しますが、templates()は提供しません。templete()は<a href="http://search.cpan.org/dist/Module-Starter-Plugin-SimpleStore/">Module-Starter-Plugin-SimpleStore</a>にある、
    </p>
    <ul>
      <li><a href="http://search.cpan.org/dist/Module-Starter-Plugin-SimpleStore/lib/Module/Starter/Plugin/DirStore.pm">Module::Starter::Plugin::DirStore</a></li>
      <li><a href="http://search.cpan.org/dist/Module-Starter-Plugin-SimpleStore/lib/Module/Starter/Plugin/InlineStore.pm">Module::Starter::Plugin::InlineStore</a></li>
      <li><a href="http://search.cpan.org/dist/Module-Starter-Plugin-SimpleStore/lib/Module/Starter/Plugin/ModuleStore.pm">Module::Starter::Plugin::ModuleStore</a></li>
    </ul>
    <p>
      のいずれか一つの中から提供されます。<br />
      幸い、Module::Starter::Plugin::TT2の中でModule::Starter::Plugin::ModuleStoreに対応するフォーマットでテンプレートが記載されているので、まずはそれを利用しましょう。
    </p>
    <p>
      configは下記のように記述します。
    </p>
    <pre>plugins: Module::Starter::Simple Module::Starter::Plugin::Template Module::Starter::Plugin::ModuleStore Module::Starter::Plugin::TT2
template_module: Module::Starter::Plugin::TT2</pre>
    <p>
      これでModule::Starter::Plugin::TT2で指定されたフォーマットでモジュールが生成されます。
    </p>
    <p>
      ここのtemplate_moduleで指定したモジュールですが、MODULE_TEMPLATE_MODULE環境変数を優先的に適用するので、特定のプロジェクトなどでModuleStoreベースでモジュールの生成を行いたい時などはカスタムのModuleStoreクラスを作ると言うのも良いかもしれません。
    </p>
    <p>
      InlineStoreはモジュールでは無く実ファイルに同等のシンタックスで記述します。<br />
      template_file, MODULE_TEMPLATE_FILE環境変数に実ファイルを指定します。
    </p>
    <p>
      DirStoreだけやってみましょう。
    </p>
    <p>
      親切な事にModule-Starter-Plugin-TT2の中にtemplatesとして<a href="http://search.cpan.org/src/RJBS/Module-Starter-Plugin-TT2-0.123/templates/dir/" title="Module::Starter::Plugin::DirStore用のテンプレート">DirStore用のテンプレート</a>も入ってます。<br />
      これを適当なディレクトリにコピーして実行します。
    </p>
    <pre>plugins: Module::Starter::Simple Module::Starter::Plugin::Template Module::Starter::Plugin::DirStore Module::Starter::Plugin::TT2
template_dir: /home/zigorou/.module-starter/test/</pre>
    <p>
      のようにconfigを書き換えます。template_dirがテンプレートを展開した物です。この状態で同様にテンプレートベースでモジュールが生成されます。
    </p>
  </div>
  <div class="section">
    <h3>まとめ</h3>
    <p>
      他にもXS用の<<a href="http://search.cpan.org/dist/Module-Starter-XSimple/" title="XS用のModule::Starterプラグイン">Module-Starter-Plugin-XSimple</a>と言うのも存在します。<br />
      またテンプレートによって自分好みの初期ファイルを作る事も出来ます。新しいdeveloper向けリリースの<a href="http://search.cpan.org/~rjbs/Module-Starter-1.43_01/" title="Module::Starterの開発者向けリリース">1.43_01</a>ではModule::Installに対応とありましたが、これも既存の枠組みだけで対応する事も当然可能です。
    </p>
    <p>
      さらに余談ですが、1.43_01に含まれるModule::Starter::Plugin::Templateですがこのままだと使えません。全てのgutsメソッドで正しくreturnすれば問題なく動作します。<br />
      一応パッチ作ったので置いておきます。
    </p>
    <dl>
      <dt>Module::Starter::Template 0.02 patch</dt>
      <dd><a href="https://labs.cybozu.co.jp/blog/yamaguchi/Module-Starter-Template_0.02.patch">download</a></dd>
    </dl>
  </div>
</div>
]]>
   </content>
</entry>
<entry>
   <title>JSON::DWIW vs JSON::Syck vs JSON</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/03/jsondwiw_vs_jsonsyck_vs_json.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1150</id>
   
   <published>2007-03-22T07:32:25Z</published>
   <updated>2007-03-22T07:56:11Z</updated>
   
   <summary> 最近CPANにJSON::DWIWというJSON parserがリリースされて...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="CPAN" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="16" label="CPAN JSON Perl Benchmark" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>
最近<a href="http://www.cpan.org/" title="CPAN">CPAN</a>に<a href="http://search.cpan.org/dist/JSON-DWIW" title="JSON::DWIW">JSON::DWIW</a>というJSON parserがリリースされて居ました。<br />
このモジュールのPODにはBenchmarkの結果があり、<a href="http://search.cpan.org/dist/JSON/">JSON</a>, <a href="http://search.cpan.org/dist/YAML-Syck/">JSON::Syck</a>とのベンチ結果が載っていますが、なんと<strong>JSON::Syckより速い</strong>との結果が出ています！
</p>
<p>
ちょっと気になったので自分でもベンチマークを取ってみました。
</p>]]>
      <![CDATA[<div class="section">
<h2>ソース</h2>
<p>下記のような感じです。</p>
<pre><code>
<span class="synPreProc">#!/usr/bin/perl</span>

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

<span class="synPreProc">use </span>Benchmark;
<span class="synPreProc">use </span>Data::Dump <span class="synConstant">qw/dump/</span>;
<span class="synPreProc">use </span>File::Slurp;
<span class="synPreProc">use </span>JSON <span class="synConstant">qw()</span>;
<span class="synPreProc">use </span>JSON::Syck;
<span class="synPreProc">use </span>JSON::DWIW;

<span class="synStatement">our</span> <var>$json_file</var> = <var>$ARGV[</var><span class="synConstant">0</span><span class="synIdentifier">]</span>;

<span class="synStatement">die</span>(<span class="synConstant">&quot;not json file&quot;</span>) <span class="synStatement">unless</span> (<var>$json_file</var> &amp;&amp; <span class="synStatement">-e</span> <var>$json_file</var>);

<span class="synStatement">our</span> <var>$json_data</var> = File::Slurp::slurp(<var>$json_file</var>);

<span class="synStatement">sub</span><span class="synIdentifier"> json_to_obj </span>{
    <span class="synStatement">my</span> <var>$json_data</var> = <span class="synStatement">shift</span>;

    JSON::jsonToObj(<var>$json_data</var>);
}

<span class="synStatement">sub</span><span class="synIdentifier"> json_to_obj_syck </span>{
    <span class="synStatement">my</span> <var>$json_data</var> = <span class="synStatement">shift</span>;

    JSON::Syck::Load(<var>$json_data</var>);
}

<span class="synStatement">sub</span><span class="synIdentifier"> json_to_obj_dwiw </span>{
    <span class="synStatement">my</span> <var>$json_data</var> = <span class="synStatement">shift</span>;

    JSON::DWIW-&gt;from_json(<var>$json_data</var>);
}

timethese(
    <span class="synConstant">10000</span>, {
        <span class="synConstant">&#39;JSON&#39;</span> =&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ json_to_obj(<var>$json_data</var>); },
        <span class="synConstant">&#39;JSON::Syck&#39;</span> =&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ json_to_obj_syck(<var>$json_data</var>) },
        <span class="synConstant">&#39;JSON::DWIW&#39;</span> =&gt;<span class="synIdentifier"> </span><span class="synStatement">sub</span><span class="synIdentifier"> </span>{ json_to_obj_dwiw(<var>$json_data</var>) }
    }
);
</code></pre>
</div>
<div class="section">
<h2>ベンチマーク結果</h2>
<p>下記のようになりました。</p>
<pre>
Benchmark: timing 10000 iterations of JSON, JSON::DWIW, JSON::Syck...
      JSON: 180 wallclock secs (179.36 usr +  0.12 sys = 179.48 CPU) @ 55.72/s (n=10000)
JSON::DWIW: 12 wallclock secs (12.04 usr +  0.01 sys = 12.05 CPU) @ 829.88/s (n=10000)
JSOJSON::Syck: 37 wallclock secs (36.48 usr +  0.23 sys = 36.71 CPU) @ 272.41/s (n=10000)
</pre>
<p>JSONモジュールが話にならない位遅いのは予想通りとして、JSON::Syckよりも約３倍速いと言える結果が出ました。これは凄い。</p>
<p>まだリリースしたてのモジュールみたいなんである程度枯れて欲しいとは思いますが、今後注目のモジュールですね。</p>
</div>
<div class="section">
<h2>追記</h2>
<p>実験用データを晒すべきとのコメントを早くも頂きましたので、<a href="http://del.icio.us/feeds/json/tags/zigorou?raw">こちら</a>がテストデータです。</p>
</div>]]>
   </content>
</entry>
<entry>
   <title>よろしくお願い致します</title>
   <link rel="alternate" type="text/html" href="https://labs.cybozu.co.jp/blog/yamaguchi/2007/03/post.html" />
   <id>tag:labs.cybozu.co.jp,2007:/blog/yamaguchi//14.1147</id>
   
   <published>2007-03-19T08:14:30Z</published>
   <updated>2007-03-19T08:20:09Z</updated>
   
   <summary>3月よりjoinしました山口です。 webのインターフェースにまつわる話からPe...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Info" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="13" label="info" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="14" label="お知らせ" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="https://labs.cybozu.co.jp/blog/yamaguchi/">
      <![CDATA[<p>3月よりjoinしました<a href="/yamaguchi.html" title="山口 徹の自己紹介">山口</a>です。</p>
<p>
webのインターフェースにまつわる話から<strong>Perl</strong>や<strong>Linux</strong>の話をメインにブログで公開して行きたいと思います。
よろしくお願い致します。
</p>]]>
      
   </content>
</entry>

</feed>
