<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Born Too Late</title>
	<atom:link href="http://blog.yuyat.jp/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yuyat.jp</link>
	<description>Yuya&#039;s tech blog.</description>
	<lastBuildDate>Sat, 31 Mar 2012 07:01:21 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>第58回PHP勉強会@東京でいろいろ話してきた</title>
		<link>http://blog.yuyat.jp/archives/1874</link>
		<comments>http://blog.yuyat.jp/archives/1874#comments</comments>
		<pubDate>Sat, 31 Mar 2012 07:01:21 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1874</guid>
		<description><![CDATA[初参加の第 56 回以降, 3 回連続で参加・発表させていただいています. 第56回PHP勉強会＠関東で PHPUnit について話してきた 第57回PHP勉強会＠東京で開発環境構築について話して来た 今回は通常の発表枠 [...]]]></description>
			<content:encoded><![CDATA[<p>初参加の第 56 回以降, 3 回連続で参加・発表させていただいています.</p>
<ul>
<li><strong><a href="http://blog.yuyat.jp/archives/1386">第56回PHP勉強会＠関東で PHPUnit について話してきた</a></strong></li>
<li><strong><a href="http://blog.yuyat.jp/archives/1461">第57回PHP勉強会＠東京で開発環境構築について話して来た</a></strong></li>
</ul>
<p>今回は通常の発表枠で自作の MapReduce フレームワーク MyMR について紹介し, 懇親会でもスライド無しでの LT をさせていただきました.</p>
<p><strong>PHP と MySQL でカジュアルに MapReduce する</strong></p>
<p>最近書いたブログ記事と全くのどうタイトルで発表させていただきました.<br />
内容的にも大体はそこに書いてあることで, 特に新しい内容は特に入れてません.</p>
<div style="width:425px" id="__ss_12172289"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/taketyan/php-mysql-mapreduce" title="PHP と MySQL でカジュアルに MapReduce する" target="_blank">PHP と MySQL でカジュアルに MapReduce する</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/12172289" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/taketyan" target="_blank">Yuya Takeyama</a> </div>
</p></div>
<p>SlideShare 上では既にはてブがたくさんついていてありがたい限りなんですが, Hadoop もやったことないのに MapReduce を語るという大変イタい内容なので, 間違いなどがあれば <a href="https://twitter.com/yuya_takeyama">@yuya_takeyama</a> までご指摘いただければ幸いです.</p>
<p>MyMR についてはの紹介記事はこちらです.</p>
<ul>
<li><strong><a href="http://blog.yuyat.jp/archives/1706">PHP と MySQL でカジュアルに MapReduce する</a></strong></li>
<li><strong><a href="http://blog.yuyat.jp/archives/1853">もっとカジュアルに PHP と MySQL で MapReduce する</a></strong></li>
</ul>
<p><strong>Symfony Console 用テストライブラリ SpyOutput と Test Spy パターン, またはその命名問題について</strong></p>
<p>こちらは懇親会 LT でスライド無しで発表しました.<br />
即興と言えば即興ですが, 内容としてはブログにまとめた内容からになります.</p>
<ul>
<li><strong><a href="http://blog.yuyat.jp/archives/1829">Symfony の Console の出力をテストする SpyOutput 書いた</a></strong></li>
</ul>
<p>大体以下のようなことを話しました.</p>
<ul>
<li>モックを使ってテストを書いた結果後悔する, ということは起こりがち</li>
<li>テスト項目が実装の詳細に寄ってしまいがち</li>
<li>Test Spy で済ませられるならその方が低コストで可読性/メンテナビリティの高いテストが書ける</li>
<li>SpyOutput の紹介</li>
<li>モックを使わないと書けないテストがあることも確か</li>
<li>これは本当にモックを使うべきなのか, については熟考する必要がある</li>
</ul>
<p>この日は <a href="http://twitter.com/fivestr"><strong>@fivestr</strong></a> さんによる<a href="http://www.slideshare.net/fivestar/20120327-phpstudy58phake">モックオブジェクトフレームワーク Phake についての発表</a>があって, そこに触発された部分もあります.</p>
<p>以上前半の半分が発表で, 後半はこちらから会場に向かって質問させていただきました.<br />
これも内容は SpyOutput の記事中に書いたもので, 「Symfony 等を拡張する単機能ライブラリを書いた場合, そのベンダープリフィクスはどうするべきか」というものです.</p>
<p>いただいた意見は以下のような感じです.</p>
<ul>
<li>自分の名前を使う</li>
<li>カッコいい名前を考える</li>
<li>自分の名前を使ったカッコいい名前を考える</li>
</ul>
<p>いずれにせよ命名センスが求められるようです&#8230;</p>
<p>結論としてはとりあえず Symfony 本体に Pull Request を送ってみて, ダメならそこでベンダープリフィクスを検討する, という方向で考えています.</p>
<p><strong>終わりに</strong></p>
<p>今回は懇親会でもデザインパターンについてなど, いろいろ会話の場を持てて大変楽しい勉強会となりました.<br />
主催の <strong><a href="http://twitter.com/gusagi">@gusagi</a></strong> さん, 会場提供の<strong><a href="http://voyagegroup.com/">株式会社 VOYAGE GROUP</a></strong> さん, 本当にありがとうございました.</p>
<p><strong>あわせて読みたい</strong></p>
<ul>
<li><strong><a href="http://fivestar.hatenablog.com/entry/2012/03/28/091944">PHP勉強会@東京#58でPhakeの紹介をしました</a></strong></li>
<li><strong><a href="http://www.slideshare.net/fivestar/20120327-phpstudy58phake">Phakeで簡単モックオブジェクト作成</a></strong></li>
<li><strong><a href="http://speakerdeck.com/u/sotarok/p/introduction-of-php-54">入門 PHP 5.4 / Introduction of PHP 5.4</a></strong></li>
<li><strong><a href="http://d.hatena.ne.jp/sotarok/20120328/1332864411">PHP勉強会@東京 #58 で「入門PHP5.4」の話をしました</a></strong></li>
<li><strong><a href="http://d.hatena.ne.jp/gusagi/20120330/1333038745">第58回PHP勉強会@東京を開催しました</a></strong></li>
<li><strong><a href="http://d.hatena.ne.jp/gallu/20120329">第58回PHP勉強会@東京に参加してきました</a></strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1874/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>もっとカジュアルに PHP と MySQL で MapReduce する</title>
		<link>http://blog.yuyat.jp/archives/1853</link>
		<comments>http://blog.yuyat.jp/archives/1853#comments</comments>
		<pubDate>Sun, 25 Mar 2012 12:00:13 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[MyMR]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1853</guid>
		<description><![CDATA[以前紹介した MapReduce フレームワーク MyMR の開発を少し進めました. パッケージとしてのリリースはまだですが. この記事では変更点等について紹介します. MyMR の仕組みなどについては前回の記事を参照し [...]]]></description>
			<content:encoded><![CDATA[<p>以前紹介した MapReduce フレームワーク <strong><a href="https://github.com/yuya-takeyama/mymr">MyMR</a></strong> の開発を少し進めました.<br />
パッケージとしてのリリースはまだですが.</p>
<p>この記事では変更点等について紹介します.</p>
<p>MyMR の仕組みなどについては前回の記事を参照してください.</p>
<ul>
<li><strong><a href="http://blog.yuyat.jp/archives/1706">PHP と MySQL でカジュアルに MapReduce する</a></strong></li>
</ul>
<p><strong>ビルダーによる Mapper/Reducer の定義</strong></p>
<p>元々はクラスにメソッドを定義する形で行っていた Mapper/Reducer の定義を, ビルダーを使って定義できるようにしました.</p>
<p><script src="https://gist.github.com/2193058.js?file=word_count_script.php"></script></p>
<p>この方法を使った場合, Mapper も Reducer も無名関数だけで定義できるようになったので, よりカジュアルになったと言えるでしょう.</p>
<p>また, クラスベースの定義では, 入出力のテーブルをコマンドラインオプションで指定していましたが, こちらではビルダーで指定できるようになりました.<br />
なので設定ファイルの別出しすることもできるようになっています.</p>
<p>また, コマンドラインで指定した場合はそちらが優先されるので, テスト時はテスト用のデータベースを使う, ということもできます.</p>
<p>無名関数以外でも, call_user_func_array() で実行できるもの (PHP 5.4 で言うところの <a href="https://wiki.php.net/rfc/callable">callable</a>) であれば何でもいいので, インスタンスメソッドなどを Mapper として定義することもできます.</p>
<p>簡単なものは無名関数でサクッと定義してい, 複雑なものはユニットテストされたクラスのメソッドで定義する, といった使い分けができるようになっています.</p>
<p>クラスベースの定義も一応残していますが, ビルダーの方が圧倒的に使いやすいように思えるので, そのうち消すかもしれません.</p>
<p><strong>コマンド名の変更</strong></p>
<p>以前は mymr execute コマンドでクラスベースの MapReduce 定義を実行していましたが, ビルダーによる定義の追加に伴い mymr class コマンドに変更しました.</p>
<p><strong>Emitter の切り出し</strong></p>
<p>Mapper はもともと \MyMR \Base クラスの emit メソッドを $this->emit($key, $value) として読んでいましたが, 無名関数で同様のことをやるには PHP 5.4 以降の Closure::bindTo() を使用する必要が出てきてしまうため, Emitter クラスを別に作り, Mapper に引数として渡すようにしました.</p>
<p>これにより, Mapper のテスト時には Emitter をモックオブジェクトや <a href="http://blog.yuyat.jp/archives/1829">Test Spy</a> オブジェクトに差し替えてテストする, ということもできるようになりました.</p>
<p><strong>進捗の表示</strong></p>
<p>元々は実行しても無言で終了していましたが, Map と Reduce それぞれで進捗を表示するようにしました.</p>
<div id="attachment_1859" class="wp-caption aligncenter" style="width: 259px"><a href="http://blog.yuyat.jp/archives/1853/3b21d6c386cae8a37f3fe5ceb8cbcc1a-1" rel="attachment wp-att-1859"><img src="http://blog.yuyat.jp/wp-content/uploads/3b21d6c386cae8a37f3fe5ceb8cbcc1a-1.png" alt="進捗の表示" title="MyMR の進捗の表示" width="249" height="268" class="size-full wp-image-1859" /></a><p class="wp-caption-text">進捗の表示</p></div>
<p>今回 \MyMR \Progress という形で実装しましたが, これ自体の MyMR との結合は緩く, Symfony の Console コンポーネントの OutputInterface にしか依存していないので, 別で公開できればと思っています.</p>
<p><strong>まとめ</strong></p>
<p>遊びで作り始めたものですが, 少しずつ様になって来ました.<br />
まだまだ開発が安定しないので, インターフェイス等は大幅に変わる可能性があると思いますが, 引き続き開発を続けて行きたいと思います.</p>
<p>MyMR については, 3/27 の<strong><a href="http://events.php.gr.jp/events/show/109">第58回PHP勉強会@東京</a></strong>で発表する予定なので, 後日スライドを公開する予定です. (今からつくる)</p>
<p>あと, <strong><a href="http://atnd.org/events/26373">MySQL Casual Talks Vol. 3</a></strong> の LT 枠でも喋りたいと思っているんですけど, これってもう募集していないんでしょうか&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1853/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Symfony の Console の出力をテストする SpyOutput 書いた</title>
		<link>http://blog.yuyat.jp/archives/1829</link>
		<comments>http://blog.yuyat.jp/archives/1829#comments</comments>
		<pubDate>Sat, 24 Mar 2012 10:45:49 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[未分類]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[Test Spy]]></category>
		<category><![CDATA[xUTP]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1829</guid>
		<description><![CDATA[Symfony2 はいわゆるフルスタックな Web アプリケーションフレームワークではありますが, 各コンポーネントは疎結合になっており, それぞれは Symfony Component として再利用できる形で公開されて [...]]]></description>
			<content:encoded><![CDATA[<p>Symfony2 はいわゆるフルスタックな Web アプリケーションフレームワークではありますが, 各コンポーネントは疎結合になっており, それぞれは Symfony Component として再利用できる形で公開されています.<br />
その中でも <a href="http://symfony.com/doc/current/components/console.html">Console コンポーネント</a>は <a href="http://behat.org/">Behat</a> や <a href="http://getcomposer.org/">Composer</a>, また <a href="http://packagist.org/packages/piece/stagehand-testrunner">Stagehand_TestRunner</a> など, あらゆる PHP アプリケーションに利用されています.</p>
<p>その Console コンポーネントを使った際に, 出力のユニットテストを行うための SpyOutput というものを書きました.<br />
これは <strong><span class="isbn_anchor"><a href="http://www.amazon.co.jp/o/ASIN/0131495054/yuyat-22/">xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))</a></span></strong> でいうところの <strong>Test Spy</strong> という方法を使ってテストを行います.</p>
<p><strong><a href="https://github.com/yuya-takeyama/console-output-spyoutput">yuya-takeyama / console-output-spyoutput</a></strong></p>
<p><strong>Test Spy とは</strong></p>
<p>分類についてちゃんと理解できていない可能性もあるので, 今の所の自分の理解として書きます.</p>
<p>Test Spy オブジェクトはモックやスタブ同様, テストのために使用する偽物のオブジェクトの一種です.<br />
本来使うべきオブジェクトの代わりにテスト対象に差し込んで, テスト対象の動作を行ったあとで, <strong>Test Spy に問い合わせることで検証を行う</strong>, というものです.</p>
<p>説明だけではわかりにくいと思うので以下の PHPUnit によるテストコードをご覧ください.</p>
<p><script src="https://gist.github.com/2180749.js?file=ApplicationTest.php"></script></p>
<p>Application クラスはコンストラクタで OutputInterface (Console コンポーネントに含まれるインターフェイスです) を実装したオブジェクトを受け取り, 出力はそのオブジェクトに委譲します.</p>
<p>本来であれば ConsoleOutput 等をセットするところを, 代わりにこの SpyOutput をセットしています.<br />
SpyOutput は OutputInterface を実装しているので, タイプヒンティングで OutputInterface が指定されていても問題ありません.</p>
<p>ConsoleOutput は write() や writeln() といったメソッドに文字列を渡すことで, その文字列を標準出力に出力しますが, SpyOutput は代わりにインスタンス変数内に溜め込みます.</p>
<p>Application オブジェクトの実行が完了したあとに, getMessage() メソッドで SpyOutput オブジェクトに問い合わせることで, 本来であればどのような出力がされるところだったのか, を問い合わせることができます.</p>
<p><strong>車輪の再発明では無いのか</strong></p>
<p>作ってから気づいたのですが, Console コンポーネントには既に出力をテストするためのクラスが存在していました.</p>
<ul>
<li><a href="https://github.com/symfony/Console/blob/master/Tester/ApplicationTester.php">ApplicationTester</a></li>
<li><a href="https://github.com/symfony/Console/blob/master/Tester/CommandTester.php">CommandTester</a></li>
</ul>
<p>Console コンポーネントはそもそもの謳い文句が <em>&#8220;Console eases the creation of beautiful and testable command line interfaces.&#8221;</em> となっており, いわばこれらのクラスもひとつのウリである, と考えられます.</p>
<p>ちょっと考えましたが, それでも SpyOutput は私にとって必要だと思いました.</p>
<p>これらは Console コンポーネント標準の Application や Command といった, 粒度の荒い単位でのテストを想定して作られたものであり, それより粒度の細かい単位のコンポーネントがある場合は適用することができません.</p>
<p>そもそも私がこれを必要としたのは, あるコマンドラインアプリケーションにおいて, その進捗状況を表示する Progress というコンポーネントを書いていて, そのテストに必要だった, というのがあります.</p>
<p>Progress の使用イメージは大体以下のような感じです.</p>
<p><script src="https://gist.github.com/2180749.js?file=SomeCommand.php"></script></p>
<p>これを Command という単位でテストしようとした場合, Progress とは関係の無い出力までそこに含まれてしまう可能性があります.</p>
<p>その可能性をできる限り排除するには, Application でも Command でもなく Progress 自体をユニットテストするのが良いでしょう.</p>
<p><script src="https://gist.github.com/2180749.js?file=ProgressTest.php"></script></p>
<p>このように, SpyOutput を使うことで, Progress だけをテストすることができました.</p>
<p>Progress は Symfony の Console コンポーネントの Application や Command のことは知らず, OutputInterface のみにしか依存していません. 進捗表示機能を SomeCommand 自体に持たせるのに比べると, 疎結合で, 再利用性の高い設計と言えるでしょう.</p>
<p><strong>命名問題</strong></p>
<p>長々と SpyOutput について説明してきましたが, 実はこのライブラリまだきちんとしたリリースができていません.<br />
というのも, ベンダープリフィクスをどうすべきか迷っていて, 今のところ Perl っぽく X をつけて <a href="http://www.symphonyx.com/">SymfonyX</a> などとしているためです.</p>
<p>Symfony のためのライブラリとはいえ, 勝手に Symfony というベンダープリフィクスを使うのは多分ダメだろうし, そうなると何というプリフィクスを付けるべきでしょう?<br />
どなたか教えてください.</p>
<p>(Symfony 本体に Pull Request 投げて取り入れてもらえると楽なんだけど&#8230;)</p>
<p><strong>まとめ</strong></p>
<p>この記事では Symfony の Console コンポーネントの出力をテストするライブラリ SpyOutput と, Test Spy というテスト手法について説明しました.<br />
命名問題が解決したら, Packagist 辺りに公開するつもりです.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1829/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP でも retry-handler を実装した</title>
		<link>http://blog.yuyat.jp/archives/1818</link>
		<comments>http://blog.yuyat.jp/archives/1818#comments</comments>
		<pubDate>Mon, 19 Mar 2012 17:02:29 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1818</guid>
		<description><![CDATA[Peercastでどんな配信してるか可視化してくれるサイト作った。 kimoto/retry-handler Ruby の retry-handler が激しく便利そうなので Java で実装してみた yoshiori/ [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><strong><a href="http://kimoto.hatenablog.com/entry/2012/03/05/103052">Peercastでどんな配信してるか可視化してくれるサイト作った。</a></strong></li>
<li><strong><a href="https://github.com/kimoto/retry-handler">kimoto/retry-handler</a></strong></li>
<li><strong><a href="http://d.hatena.ne.jp/Yoshiori/20120315/1331825419">Ruby の retry-handler が激しく便利そうなので Java で実装してみた</a></strong></li>
<li><strong><a href="https://github.com/yoshiori/retry-handler">yoshiori/retry-handler</a></strong></li>
</ul>
<p>便利そうだったので PHP でも実装しました.<br />
Packagist に公開したので Composer でインストールできます.</p>
<ul>
<li><strong><a href="https://github.com/yuya-takeyama/retry-handler-php">yuya-takeyama/retry-handler-php</a></strong></li>
<li><strong><a href="http://packagist.org/packages/retry-handler/retry-handler">retry-handler/retry-handler</a></strong></li>
</ul>
<p>何をするものかというと, 例えば HTTP リクエストなど, 失敗する可能性のある処理をリトライしよう, というときの処理を抽象化するためのものです.</p>
<p><strong>インストール</strong></p>
<p>Composer を使用するので, 適当なディレクトリに composer.json を用意します.</p>
<p><script src="https://gist.github.com/2118768.js?file=composer.json"></script></p>
<p>そして以下のコマンドを実行すると Composer 自体をインストールした後, Composer で RetryHandler が ./vendor ディレクトリにインストールされます.</p>
<p><script src="https://gist.github.com/2118768.js?file=INSTALL"></script></p>
<p><strong>使い方</strong></p>
<p><script src="https://gist.github.com/2118768.js?file=test.php"></script></p>
<p>無名関数をラップして, リトライしたい処理を Proc オブジェクトとして生成します.<br />
retry() メソッドを呼び出すと引数に呼び出した数だけリトライ処理を行い, 全て失敗した場合は RetryOverException がスローされます.</p>
<p><strong>リトライ対象の例外を指定する</strong></p>
<p>デフォルトでは RuntimeException かそのサブクラスがスローされた場合のみリトライを行い, それ以外 (例えば LogicException など) の例外がスローされたら強制的に終了となります.</p>
<p>あるライブラリがスローする例外のみを想定してリトライし, それ以外はエラーとする, といった場合は accepted_exception オプションを使用することで実現できます.</p>
<p><script src="https://gist.github.com/2118768.js?file=accepted_exception.php"></script></p>
<p><strong>待ち時間を入れる</strong></p>
<p>リトライの前に待ち時間を入れたい, というときは wait オプションを使い, 待ち時間を秒単位で指定できます.<br />
デフォルトでは 1 秒になっています.</p>
<p><script src="https://gist.github.com/2118768.js?file=wait.php"></script></p>
<p><strong>まとめ</strong></p>
<p>元の Ruby の実装だと Parallel や Thread を使ったとてもクールな実装になっていて, 素の PHP だとそこまではできなさそうな感じではありますが, リトライ処理自体は PHP でも割とやると思うので, 奇麗に書けるといいんじゃないかと思います.</p>
<p>RetryHandler はとりあえず動いた, 程度のレベルで, まだまだ使えない (例えば, Proc の中の値どうやって取るんだ, とか) と思うんですが, その辺りは今後気まぐれで改善していければという感じです.</p>
<p>ところで 2 年程まえにちょうど同じような需要があって作った <a href="https://github.com/yuya-takeyama/Retrial"><strong>Retrial</strong></a> というものがあるんですけど, 今見るととても酷いコードで, テストも何がやりたいのかわからない感じ.<br />
まぁこの頃よりはまだマシなコードが書けるようになったんだなと自分を納得させています.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1818/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>このブログからはてなブックマークボタンを削除しました</title>
		<link>http://blog.yuyat.jp/archives/1779</link>
		<comments>http://blog.yuyat.jp/archives/1779#comments</comments>
		<pubDate>Sun, 11 Mar 2012 05:12:52 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Hatena]]></category>
		<category><![CDATA[microad]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1779</guid>
		<description><![CDATA[キャッチアップが一足遅れてしまいましたが, 何となく状況を把握できたのでアクションを起こした次第です. はてなブックマークボタンのトラッキング問題で高木浩光先生が決別ツイートをするに至った経緯まとめ ところでこの NAV [...]]]></description>
			<content:encoded><![CDATA[<p>キャッチアップが一足遅れてしまいましたが, 何となく状況を把握できたのでアクションを起こした次第です.</p>
<p><strong><a href="http://matome.naver.jp/odai/2133131006928771201">はてなブックマークボタンのトラッキング問題で高木浩光先生が決別ツイートをするに至った経緯まとめ</a></strong></p>
<p>ところでこの NAVER まとめページを見ていると, *.microad.jp へのトラッキングリクエストが複数行われるのは何なんでしょうか?</p>
<div id="attachment_1782" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/1779/microad" rel="attachment wp-att-1782"><img src="http://blog.yuyat.jp/wp-content/uploads/microad-300x29.png" alt="microad へのトラッキングのキャプチャ" title="microad へのトラッキングのキャプチャ" width="300" height="29" class="size-medium wp-image-1782" /></a><p class="wp-caption-text">microad へのトラッキングのキャプチャ</p></div>
<p><strong>このブログに行った対応</strong></p>
<ul>
<li>はてなブックマークボタンの削除 (<a href="http://wordpress.org/extend/plugins/wp-social-bookmarking-light/">WP Social Bookmarking Light</a> というプラグインの設定)</li>
<li><a href="http://zenback.jp/">Zenback</a> のはてなブックマークボタンの削除 (Zenback の管理画面から)</li>
<li>Zenback のはてなブックマークコメントの削除 (Zenback の管理画面から)</li>
</ul>
<p>同様の対応を GitHub Pages で書いている殴り書きブログ <a href="http://scribble.yuyat.jp/">Scribble</a> にも行っています.</p>
<p>はてなブックマークボタンにはトラッキングするものと<a href="http://b.hatena.ne.jp/guide/bbutton?al=0">しないもの</a> があって, WP Social Bookmarking Light ではトラッキングするもの, Zenback により埋め込まれるものはトラッキングしないものになっていました.<br />
ところが, Zenback のログアウト状態でのトップページに行くとはてなブックマークボタンがあり, これはトラッキングするもので, track.send.microad.jp へのリクエストが確認できました.</p>
<p>このブログでははてなスターも使っていますが, これはそのままにしてあります.<br />
特にトラッキングっぽいことをしていわけでは無さそうだということもありますが, テンプレートに直書きで入れてて外すのが面倒だというのもあります.</p>
<p>また, WordPress では例えば WP Super Cache といったキャッシュプラグインを使用している場合はキャッシュに残っていることがあるので, 削除しておく必要があります.<br />
これは WP Super Cache の管理画面からすぐできました.</p>
<p><strong>個人的に行った対応</strong></p>
<ul>
<li>ローカルマシンの /etc/hosts を書き換えて *.microad.jp のいくつかを 127.0.0.1 に向けた</li>
<li>Chrome のはてなブックマーク拡張をアンインストール</li>
</ul>
<p>/etc/hosts には以下のような行を追加しました.</p>
<p><script src="https://gist.github.com/2015067.js?file=hosts"></script></p>
<p>CDN っぽいのは別にいいような気もしますが, js ファイルを拒否しておくのは効果がありそうなのでやってみました.<br />
数もそんなに多くないし.</p>
<p>これを追加してからは Wireshark に microad っぽいパケットが引っかからなくなりました.</p>
<div id="attachment_1797" class="wp-caption aligncenter" style="width: 638px"><a href="http://blog.yuyat.jp/archives/1779/wireshark" rel="attachment wp-att-1797"><img src="http://blog.yuyat.jp/wp-content/uploads/wireshark.png" alt="Wireshark による microad のキャプチャ" title="Wireshark による microad のキャプチャ" width="628" height="124" class="size-full wp-image-1797" /></a><p class="wp-caption-text">Wireshark による microad のキャプチャ</p></div>
<p><del datetime="2012-03-11T10:17:19+00:00">&#8230;といってもリクエスト先の IP がデタラメなだけでリクエスト自体は行われているはずなので, Destination が 127.0.0.1 のものが引っかかりそうな気はするんですが, やり方が悪いんでしょうか.<br />
どなたか教えていただきたいです.</del></p>
<p><strong>トラッキングされるものとされないものの違い</strong></p>
<p><a href="http://b.hatena.ne.jp/guide/bbutton?al=0">トラッキングされないもの</a>の埋め込みコードを確認したところ, script タグで指定しているファイルが違うだけでした.</p>
<ul>
<li>トラッキングされるもの
<p>http://b.st-hatena.com/js/bookmark_button.js</li>
<li>トラッキングされないもの
<p>http://b.st-hatena.com/js/bookmark_button_wo_al.js</li>
</ul>
<p>要するにファイル名に _wo_al があるかないかだけの違いなので, はてなブックマークボタンを使い続けたい場合は _wo_al をつける (もしくはそうなっているか確認する) という手段もあるでしょう.</p>
<p><strong>WP Social Bookmarking Light について</strong></p>
<p>前述の通り, WP Social Bookmarking Light では行動履歴がトラッキングされるタイプのはてなブックマークボタンが使用されるようになっていたので, <a href="https://github.com/utahta/WP-Social-Bookmarking-Light/pull/9">Pull Request</a> を送らせていただきました.<br />
これが取り込まれれば, WP Social Bookmarking Light を使ってはてなブックマークボタンを表示させても, それにより行動履歴のトラッキングは行われなくなります.</p>
<p><del datetime="2012-03-11T13:45:45+00:00">とはいえそれがいつになるかはわからないので, 取り急ぎは前述の通りプラグインの中身で _wo_al を付加した js ファイルを指定する方法を取るのがいいでしょう.<br />
</del></p>
<p><strong>まとめ</strong></p>
<p>私自身ははてなブックマークをそんなに利用している方では無いと思いますが, 今回の問題は残念としか言いようがありません.<br />
最近のアップグレードが素晴らしかっただけに, 特にそう思います.</p>
<p>この件について聞いてからもしばらくははてなブックマークを使っていましたが, 何らかの対応が行われるまではしばらく使用をやめるつもりです.</p>
<p>とはいえ, はてなブックマークが提供する機能自体は素晴らしいものだと思いますし, 代替も特に思いつかないので, 良い形でまた利用できるようになればと願っています.</p>
<p><strong>2012-03-11 19:20 追記</strong></p>
<p>/etc/hosts で microad のホストを 127.0.0.1 に向けたあとに Wireshark でキャプチャできなくなった件ですが, キャプチャしているのが LAN パケット (en0) だったせいでした.<br />
ループバックパケット (lo0) をキャプチャすることで, 127.0.0.1 から 127.0.0.1 への *.microad.jp のコンテンツを要求する HTTP リクエストを確認できました.<br />
itsango さんありがとうございました.</p>
<p><strong>2012-03-11 22:50 追記</strong></p>
<p>WP Social Bookmarking Light に送った <a href="https://github.com/utahta/WP-Social-Bookmarking-Light/pull/9">Pull Request</a> が取り込まれ, <a href="http://wordpress.org/extend/plugins/wp-social-bookmarking-light/">WordPress のプラグインポータル</a>側にも反映されました.<br />
最新の 1.7.1 以降であればトラッキングしないタイプのはてなブックマークボタンに置き換わっています.</p>
<p>素早い対応をしていただいた作者の <strong><a href="https://twitter.com/#!/utahta">@utahta</a></strong> さんに感謝します.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1779/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>社内勉強会で PHPUnit とプログラマの病気について話した</title>
		<link>http://blog.yuyat.jp/archives/1773</link>
		<comments>http://blog.yuyat.jp/archives/1773#comments</comments>
		<pubDate>Fri, 09 Mar 2012 16:18:19 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1773</guid>
		<description><![CDATA[PHPUnit でテスト駆動開発を始めよう View more presentations from Yuya Takeyama 「始めよう」というタイトルを冠していながら, まったく始められる感の無いスライドになってし [...]]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_11922674"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/taketyan/phpunit-11922674" title="PHPUnit でテスト駆動開発を始めよう" target="_blank">PHPUnit でテスト駆動開発を始めよう</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/11922674" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/taketyan" target="_blank">Yuya Takeyama</a> </div>
</p></div>
<p>「始めよう」というタイトルを冠していながら, まったく始められる感の無いスライドになってしまいました.<br />
元々は PHPUnit を使ったことが無いしユニットテストとかも書いたことが無い, という人に PHPUnit に興味を持ってもらうことを目標として作っていたはずなので, それを考えると駄作もいいところ.<br />
ターゲットを明らかに見失っている.</p>
<p>ですが, ここ最近ずっと感じつつも, なかなか言語化できずにいたことをアウトプットできた, という意味では多いに価値があったと思います.<br />
42 ページ目以降の「蛇足 : オレはこう思う」が主にこのスライドで言いたかったことなんだと思います.</p>
<p>継続的に改善を重ねることで絶対精神にプリズムジャンプ, できるような環境を作って行きたい.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1773/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Travis CI の PHP 5.2 に mbstring が入った</title>
		<link>http://blog.yuyat.jp/archives/1757</link>
		<comments>http://blog.yuyat.jp/archives/1757#comments</comments>
		<pubDate>Sat, 03 Mar 2012 07:33:15 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[mbstring]]></category>
		<category><![CDATA[Travis CI]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1757</guid>
		<description><![CDATA[PHP 5.4 がめでたくリリースされましたが, 5.2 なサービスやライブラリを保守している人もまだまだいることでしょう. 移行などを考えると, とりあえずは namespace も Closure も使わずクラス名は [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://php.net/releases/5_4_0.php">PHP 5.4 がめでたくリリースされましたが</a>, 5.2 なサービスやライブラリを保守している人もまだまだいることでしょう.</p>
<p>移行などを考えると, とりあえずは namespace も Closure も使わずクラス名は Foo_Bar_Baz とかアンダースコアで区切る PHP 5.2 なスタイルで書きつつ, PHP 5.3 や 5.4 でも動作するようにライブラリを書く, という選択肢を取ることになりますが, 全部の環境でテストするのは面倒くさい&#8230;<br />
というあなたのための <strong><a href="http://travis-ci.org/">Travis CI</a></strong> というサービスについては以前書きました.</p>
<p><strong><a href="http://blog.yuyat.jp/archives/1540">Travis CI で PHP 5.4 も CI する, PHPUnit も Behat もやる</a></strong></p>
<p>そんな Travis CI ですが, PHP 5.2 に mbstring が入っておらず, そのせいで PHP 5.2 だけテストが通らない, なんてことが起こっていました.</p>
<div id="attachment_1762" class="wp-caption aligncenter" style="width: 562px"><a href="http://blog.yuyat.jp/archives/1757/fail" rel="attachment wp-att-1762"><img src="http://blog.yuyat.jp/wp-content/uploads/fail.png" alt="" title="ビルド失敗" width="552" height="638" class="size-full wp-image-1762" /></a><p class="wp-caption-text">mb_strwidth が無くてテストがコケる</p></div>
<p>ですがそれも今は昔の話, いつの間にか mbstring 入りで PHP 5.2 環境が用意されるようになったようで, 問題無くテストが通るようになっていました.</p>
<div id="attachment_1765" class="wp-caption aligncenter" style="width: 553px"><a href="http://blog.yuyat.jp/archives/1757/success" rel="attachment wp-att-1765"><img src="http://blog.yuyat.jp/wp-content/uploads/success.png" alt="" title="ビルド成功" width="543" height="686" class="size-full wp-image-1765" /></a><p class="wp-caption-text">テスト通った!</p></div>
<p>コミット識別子を見ると, どちらも同じコードに対してテストが実行されていることがわかります.</p>
<p>この修正は, Travis CI の PHP 対応に尽力なさっている <a href="https://github.com/travis-ci/travis-cookbooks/commit/23a28ba341f56a66b69e82a24f13184128f1217e">Loïc Frering</a> さんによるものです.<br />
他にも PHP の新しいバージョンが出るたびに定義ファイルを用意してくれたり, 足を向けては寝られない思いです. (ちなみにフランスの方らしいです)</p>
<p>ところで通常 Travis CI によるビルドを実行するには GitHub に対して push する必要がありますが, 今回の場合のようにコードに変更は無いが再度実行したい, という場合は, 以下の方法でできます.</p>
<ol>
<li>GitHub のリポジトリの Admin から Service Hooks, Travis と辿る</li>
<li>Test Hook ボタンを押す</li>
</ol>
<div id="attachment_1768" class="wp-caption aligncenter" style="width: 463px"><a href="http://blog.yuyat.jp/archives/1757/travis" rel="attachment wp-att-1768"><img src="http://blog.yuyat.jp/wp-content/uploads/travis.png" alt="" title="travis" width="453" height="329" class="size-full wp-image-1768" /></a><p class="wp-caption-text">GitHub 上の Travis CI の Service Hook 管理画面</p></div>
<p>これで push したときと同様の通知が行われ, Travis CI 上でのビルドを強制的に実行することができます.</p>
<p>そういうわけでまだまだ PHP 5.2 な方もどんどん Travis CI を作っていきましょう.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1757/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Padrino で Mongoid のタスクがうまく実行できていなかった件</title>
		<link>http://blog.yuyat.jp/archives/1750</link>
		<comments>http://blog.yuyat.jp/archives/1750#comments</comments>
		<pubDate>Sun, 26 Feb 2012 05:41:21 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Mongoid]]></category>
		<category><![CDATA[Padrino]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1750</guid>
		<description><![CDATA[久々に Padrino で開発していて, データベースには MongoDB, データ永続化層として Mongoid を使っています. ところがインデックスの作成が上手くできませんでした. Padrino x Mongoi [...]]]></description>
			<content:encoded><![CDATA[<p>久々に <a href="http://www.padrinorb.com/"><strong>Padrino</strong></a> で開発していて, データベースには MongoDB, データ永続化層として <a href="http://mongoid.org/"><strong>Mongoid</strong></a> を使っています.</p>
<p>ところがインデックスの作成が上手くできませんでした.<br />
Padrino x Mongoid という構成では, インデックスの作成に以下のコマンドを使います. (長い)</p>
<p><script src="https://gist.github.com/1913399.js?file=create_indexes"></script></p>
<p>コンソール上では特に問題無く終わったかのようにみえるのですが, 実際は何も起こらずに終わっていました.<br />
MongoDB のコンソールを見ても, 特にインデックスの作成が試みられたようなログは残りません.</p>
<p>調べた所, rake タスク自体に問題がありました.</p>
<p><script src="https://gist.github.com/1913399.js?file=mongoid.rb"></script></p>
<p>これはモデルクラスを探索し, 見つかったものを Class オブジェクトの配列として返すものなのですが, モデルクラスのファイルの位置の指定に間違いがあり, 常に空の配列が返って来ていました.<br />
これだと, 探索が行われるのが app/models/*.rb と /models/*.rb となってしまいますが, 実際には models/*.rb を探索する必要があります.</p>
<p><script src="https://gist.github.com/1913399.js?file=mongoid.rb.diff"></script></p>
<p>1 Byte の追加でうまく問題が解決しました.<br />
テストはもともと無かったし, ファイルシステムが絡むからめんどいなーと思って書いてません.<br />
すいません&#8230;</p>
<p>GitHub で<a href="https://github.com/padrino/padrino-framework/pull/795">報告</a>したらすぐに<a href="https://github.com/padrino/padrino-framework/commit/711bb694f04ccb681ab7b76d0b4dfabf9331b1cc">取り入れられました</a>.<br />
gem でのリリースはまだですが, これもそんなに時間はかからないと思います.</p>
<p>どうも Padrino のモデルクラスの置き場所が, ./app/models から ./models に移ったようで, <a href="https://github.com/padrino/padrino-framework/commit/66782959a1214b5f85d43ef47cbf89e99a5be9d6#diff-13">そのときの変更</a>のときからずっと壊れていたようです.<br />
多分 7 ヶ月間ずっと動いていなかったみたいなんですが, Mongoid ってあんまり使われていないんでしょうか&#8230;</p>
<p>ウェブサービスを作ろうとするとフレームワークのバグにハマり, それの修正で満足してしまって結局ウェブサービスが完成しない, という現象に名前が欲しい.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1750/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>社内勉強会で MySQL 入門的なはなしをしてきた</title>
		<link>http://blog.yuyat.jp/archives/1743</link>
		<comments>http://blog.yuyat.jp/archives/1743#comments</comments>
		<pubDate>Sat, 25 Feb 2012 03:37:46 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1743</guid>
		<description><![CDATA[MySQL 入門的なはなし View more presentations from Yuya Takeyama 社内で, 主に MySQL 初学者を対象とした勉強会をやってきました. 社内勉強会ということで, というと [...]]]></description>
			<content:encoded><![CDATA[<div style="width:425px" id="__ss_11731643"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/taketyan/mysql-11731643" title="MySQL 入門的なはなし" target="_blank">MySQL 入門的なはなし</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/11731643" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/taketyan" target="_blank">Yuya Takeyama</a> </div>
</p></div>
<p>社内で, 主に MySQL 初学者を対象とした勉強会をやってきました.<br />
社内勉強会ということで, というと言い訳になりますが, いつも以上にゆるふわな内容となっています.</p>
<p>改めて見るとソースどこだよ? っていう情報がいくつかあるので反省.<br />
(「RDBMS を使いつつ, NOSQL で最適化というパターンがほとんど」とかどこのことだよと. まぁ <a href="http://blog.kyanny.me/entry/2012/02/19/002256">Tumblr とかはそれにあたるみたいですが</a>)</p>
<p>あと, インデックスの仕組みを単純化して話すために B-Tree じゃなくて Binary Search Tree について紹介してますが, この辺も詳しい方の突っ込みが欲しい所です.</p>
<p>ところで勉強会に参加していてよく思うのですが, 勉強会というのは自分で発表してナンボだということです.<br />
これは勉強会で人の話を聞くのは意味が無い, ということではなくて, 自分で調べたときの方が 30 倍ぐらい身に付くんじゃないか, という感覚によります.<br />
どう考えても発表した方がコストパフォーマンスの高い学習ができる.</p>
<p>自分のスキルアップに繋がるからそれはそれでいいんですが, やっぱり社内でとなると, 貴重なみんなの時間を使わせてもらうことにもなるので, 出来る限り聞いてる人の身に付くような工夫を心がけたいなと思います.</p>
<p>そこで今回は, みんなで Binary Search Tree を作る, という参加型の企画を仕込んでみました.<br />
作る, といってもいきなり実装するのはハードルが高いので, ひとりひとりに適当な名前 (タロウとかハナコとか) を順に挙げてもらい, ホワイトボードに Binary Search Tree を書いていくというものです.<br />
(今思えばこれ写真に残しておけばよかった)</p>
<p>思いのほか盛り上がったし, ちゃんと理解してもらえたようでした.<br />
Head First データ構造という感じでおもしろかったです.</p>
<p>あと, スライド中で紹介しているんですが, <a href="http://academicearth.org/lectures/run-times-and-algorithms-recursion">ハーバード大学のコンピュータサイエンスの授業の動画</a>はオススメです.<br />
教授のテンションがやたら高くて白熱教室という感じ. (ついていくのが大変そうな感じではある)</p>
<p>今回の発表では, Binary Search の文脈で 4:30 辺りの, 電話帳で Binary Search と Linear Search をやってる部分をみんなで観ました.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1743/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SELECT 結果からサクッと表を生成する Tablr というのを書いた</title>
		<link>http://blog.yuyat.jp/archives/1727</link>
		<comments>http://blog.yuyat.jp/archives/1727#comments</comments>
		<pubDate>Sun, 12 Feb 2012 10:21:27 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[tablr]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1727</guid>
		<description><![CDATA[先週はビッグデータ時代の非ビッグデータ戦略として, MySQL でサクッと MapReduce する話を書きました. しかしよく考えると, 非ビッグデータを前提とする以上は, やはり普通に GROUP BY とかで済ませ [...]]]></description>
			<content:encoded><![CDATA[<p>先週はビッグデータ時代の非ビッグデータ戦略として, <a href="/archives/1706">MySQL でサクッと MapReduce する話</a>を書きました.<br />
しかしよく考えると, 非ビッグデータを前提とする以上は, やはり普通に GROUP BY とかで済ませてしまうのがよりカジュアルと言えます.</p>
<p>しかしそれをどう見せるか, ということを気にしだすと, これが何気にめんどくさい.<br />
集計時にメールで報告しつつ, 管理ツールのダッシュボード的な画面でも閲覧可能にしたい, という要求はどこにでもあると思いますが, そのときどきで書いていると, クエリを書く何十倍もの時間がかかってしまったりします.</p>
<p>そこで, 例えば RDBMS の結果セットを与えると, それをサクッと見やすく出力してくれる Tablr というのを書きました.<br />
The MIT License にて GitHub で公開しています.</p>
<p><strong><a href="https://github.com/yuya-takeyama/tablr">yuya-takeyama/Tablr &#8211; GitHub</a></strong></p>
<p>今どき PHP5.2 で書かれていますが, その辺は何となく察して下さい.<br />
大した機能は無いですが, 個人的にはこれで日頃の問題をいくつか解決できそうなので, 明日からの仕事に使っていく予定です.</p>
<p><strong>使用例</strong></p>
<p>以下は二次元の配列をもとに, プレーンテキストの表を出力するスクリプトです.</p>
<p><script src="https://gist.github.com/1807735.js?file=example.php"></script></p>
<p>ちょっと長く感じますが, require_once や表のデータの部分を除けば, 表の出力に関しては 5 行ほどしかありません.<br />
ここではデータを直接記述していますが, 実際は RDBMS に対して SELECT クエリを発行したときの結果セット等を与えることを想定しています.</p>
<p>これを実行すると以下のような表が出力されます.</p>
<p><script src="https://gist.github.com/1807735.js?file=output.txt"></script></p>
<p>以下では Tablr の機能についてより詳細に紹介します.</p>
<p><strong>フォーマッタ</strong></p>
<p>二次元の配列をもとに, いくつかの形式に出力するためのものです.<br />
これが Tablr を作りにあたっての一番のモチベーションとなっています.</p>
<p>現在利用可能なフォーマッタは以下の 2 つのみとなっています.</p>
<ul>
<li>プレーンテキストフォーマッタ</li>
<li>HTML フォーマッタ</li>
</ul>
<p><strong>アグリゲータ</strong></p>
<p>それぞれのカラムで集計を行い, テーブルのフッタにその行を追加します.<br />
現在利用可能なアグリゲータは以下の 2 つのみとなっています.</p>
<ul>
<li>合計アグリゲータ</li>
<li>平均アグリゲータ</li>
</ul>
<p>とりあえず必要最低限の機能を実装した, という感じで, 作り込みはかなり甘い感じです.<br />
使えそうな感じであれば, またさらに改善して行きたいと思います.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1727/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

