<?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 &#187; JavaScript</title>
	<atom:link href="http://blog.yuyat.jp/archives/category/tech/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.yuyat.jp</link>
	<description>Yuya&#039;s tech blog.</description>
	<lastBuildDate>Sat, 04 Feb 2012 11:25:32 +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>メタプログラミングで jQuery.ajax を Fluent Interface にする</title>
		<link>http://blog.yuyat.jp/archives/1198</link>
		<comments>http://blog.yuyat.jp/archives/1198#comments</comments>
		<pubDate>Sat, 28 May 2011 06:05:53 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Fluent Interface]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Meta-Programming]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1198</guid>
		<description><![CDATA[jQuery で Ajax リクエストを行う場合, パラメータはハッシュ (JavaScript の Object 型) で指定して実行します. この例だとまだシンプルに見えますが, success コールバックなどが肥 [...]]]></description>
			<content:encoded><![CDATA[<p>jQuery で Ajax リクエストを行う場合, パラメータはハッシュ (JavaScript の Object 型) で指定して実行します.</p>
<p><script src="https://gist.github.com/996633.js?file=using-raw-jquery.js"></script></p>
<p>この例だとまだシンプルに見えますが, success コールバックなどが肥大化してくると, 見通しが悪くなってきます.</p>
<p>そこで以下のようなコードを用意します.<br />
jQuery.ajax() のラッパーとなる FluentAjax オブジェクトと, それを呼び出すヘルパーとして fajax() 関数を定義しました.</p>
<p><script src="https://gist.github.com/996633.js?file=fluent-ajax.js"></script></p>
<p>メソッドの定義にはメタプログラミングを使用しており, 実質上のプログラムは約 30 行程度です.</p>
<p>これを利用すると, 同じ Ajax リクエストを以下のように行うことができるようになります.</p>
<p><script src="https://gist.github.com/996633.js?file=how-to-use.js"></script></p>
<p>メソッドチェインでリクエストオプションを組み立てていき, 最後に execute() メソッドでリクエストを実行しています.<br />
いわゆる Fluent Interface (流れるようなインターフェイス) になっていると思います.</p>
<p>メソッドチェインを使った方が可読性が高い&#8230; かどうかは好みの問題かもしれませんが, ひとつのサンプルとして.<br />
これをもう少し抽象化すれば, 1 つのハッシュを引数にした複雑な関数は, 何でも Fluent Interface にできそうですね.</p>
<p><strong>See also</strong></p>
<ul>
<li><a href="http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface">流れるようなインターフェイス</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1198/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript でコンストラクタを隠蔽する</title>
		<link>http://blog.yuyat.jp/archives/1152</link>
		<comments>http://blog.yuyat.jp/archives/1152#comments</comments>
		<pubDate>Sun, 06 Mar 2011 14:07:42 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1152</guid>
		<description><![CDATA[思いつきをメモ. 良い点 コンストラクタが隠蔽される JavaScript では, オブジェクトのコンストラクタは関数として定義されます. なので, new Constructor と呼び出すべきなのに, Constru [...]]]></description>
			<content:encoded><![CDATA[<p>思いつきをメモ.</p>
<p><script src="https://gist.github.com/857296.js?file=dog.js"></script></p>
<p><strong>良い点</strong></p>
<ul>
<li><strong>コンストラクタが隠蔽される</strong><br />
JavaScript では, オブジェクトのコンストラクタは関数として定義されます.<br />
なので, new Constructor と呼び出すべきなのに, Constructor() というように呼び出されることもあり得ます.</li>
<li><strong>インスタンスメソッドも隠蔽される</strong><br />
Dog.create() でオブジェクトが生成されるまでは, greet() メソッドは見えません.<br />
オブジェクトを通してしか, インスタンスメソッドにアクセスできないということです.</li>
</ul>
<p><strong>悪い点</strong></p>
<ul>
<li><strong>create() の定義が面倒</strong><br />
create() に渡された引数を, init() に渡さないといけないので, 定義がやや煩雑です.<br />
Function.apply() が使えれば, arguments を渡すだけで良さそうですが, コンストラクタを Function.apply() で呼び出すことってできるんでしょうか?<br />
解決策としては, 引数を全てハッシュ変数 (Object) にする, というのが考えられます.</li>
<li><strong>これで本当に幸になれるのか微妙</strong><br />
JavaScript では private や protected といった修飾子で, メソッドを隠蔽することはできません.<br />
普通に定義する create メソと, コンストラクタもメソッドも明け透けな状態にあります.<br />
しかし, そこは開発者の良心に委ねることでも十分解決できるのではないでしょうか.<br />
「アンダースコアから始まるメソッド, プロパティはプライベート扱い」という紳士協定を共有すればいいのではないでしょうか.<br />
Python は, そういった文化の中で利用されている言語のひとつでしょう.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1152/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript の spec を RSpec で書く</title>
		<link>http://blog.yuyat.jp/archives/1132</link>
		<comments>http://blog.yuyat.jp/archives/1132#comments</comments>
		<pubDate>Sun, 06 Mar 2011 08:33:18 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test Driven Development]]></category>
		<category><![CDATA[RSpec]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=1132</guid>
		<description><![CDATA[Ruby 以外のプログラムを書いていると, 「RSpec で spec が書けない」というだけの理由で, 億劫になってしまうことがあります. RSpec で JavaScript の spec が書ければ&#8230;  [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby 以外のプログラムを書いていると, <strong>「RSpec で spec が書けない」</strong>というだけの理由で, 億劫になってしまうことがあります.<br />
RSpec で JavaScript の spec が書ければ&#8230; そう思って, やってみました.</p>
<p>まずは実際のコードを説明なしに紹介し, 環境構築手順や, 解説については後述します.</p>
<p><strong>テスト対象 (System Under Test)</strong></p>
<p>今回はこの JavaScript のコードを対象に, spec を書いてみます.</p>
<p><script src="https://gist.github.com/857112.js?file=message_filter.js"></script></p>
<p>とりあえずは<strong>「RSpec で JavaScript の spec が書けるのか」</strong>という検証が目的なので, シンプルなもので十分でしょう.<br />
t-wada さん<a href="http://d.hatena.ne.jp/t-wada/20100228/p1"><strong>のRSpec の入門とその一歩先へ</strong></a>をそのまま JavaScript にしてみたようなものです.</p>
<p>detect メソッドに渡す文字列の中に, コンストラクタに渡された単語が含まれるか, を検証するだけの簡単なオブジェクトです.</p>
<pre>
$ js
Rhino 1.7 release 2 2010 09 15
js> load("message_filter.js")
js> var filter = new MessageFilter("foo");
js> filter.detect("foo bar baz");
true
js> filter.detect("Hello, World!");
false
</pre>
<p><strong>spec</strong></p>
<p>上記のコードをテストするための spec です.</p>
<p><script src="https://gist.github.com/857112.js?file=message_filter_spec.rb"></script></p>
<p>MessageFilter というクラスは Ruby 上で定義されているわけではないので, ここでは Symbol 型を利用しています.</p>
<p>これを実行すると, 以下のようになります.</p>
<pre>
$ rspec -fs message_filter_spec.rb 

MessageFilter with argument "foo"
  should detect from "foo bar baz"
  should detect from "Hello World!"

Finished in 0.40217 seconds
2 examples, 0 failures
</pre>
<p>一応の動作は確認できましたね.</p>
<p><strong>環境の構築</strong></p>
<p>今回は以下のような環境を使用しています.<br />
OS は Ubuntu 10.10 です.</p>
<pre>
$ ruby -v
ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-linux]
$ rspec -v
2.5.1
$ gem list # 一部省略

*** LOCAL GEMS ***

harmony (0.5.6)
johnson (2.0.0.pre3)
rspec (2.5.0)
rspec-core (2.5.1)
stackdeck (0.2.0)
</pre>
<p>普段は Ruby 1.9.2 を使用しているのですが, 今回使用する harmony という gem の依存ライブラリである johnson が, 1.9.x ではインストールできないようなので, 1.8.7 を使用しています.<br />
RVM を利用して複数の Ruby 環境を切り替えられる環境であれば, さほど問題は無いでしょう.</p>
<p>以下のようにインストールします. (Ruby, RVM のインストールは省略)</p>
<pre>
$ gem install stackdeck
$ gem install johnson -v "2.0.0.pre3"
$ gem install harmony
$ gem install rspec
</pre>
<p>harmony のインストール時には, 依存ライブラリである stackdeck と johnson も一緒にインストールされるべきですが, 現在は問題があってうまくできないようです.<br />
とりあえず手動でインストールしておけば問題ありません.</p>
<p><strong>どういう仕組みで動いているのか</strong></p>
<p><strong><a href="https://github.com/jbarnette/johnson">Johnson</a></strong> が Ruby 上での JavaScript (SpiderMonkey) の実行環境を提供し, <strong><a href="https://github.com/mynyml/harmony">Harmony</a></strong> はそれをラップした DSL, とのことです.</p>
<p>Harmony::Page オブジェクトが .js ファイルを読み込んだコンテキストを保持し. x メソッド (execute_js メソッドのエイリアス) でプログラムを実行することができます.<br />
x メソッドで実行した JavaScript プログラム中, 最後に評価された値が返り値として Ruby に渡されます.<br />
(ただし, オブジェクトは返らないらしい)</p>
<p><strong>問題点</strong></p>
<ul>
<li><strong>可読性が低い</strong><br />
JavaScript のコードを文字列リテラルで書かざるを得ないこともあり, とても読みやすいとは言えないでしょう.<br />
RSpec はメタプログラミングにより &#8220;Test as Documentation&#8221; (ドキュメントとしてのテスト) を簡単に書かせてくれるはずですが. ここではその力を発揮できていません.</li>
<li><strong>Object の検証ができない</strong><br />
前述のとおり, Harmony は JavaScript の Object 型の値を Ruby に渡してくれません.<br />
JavaScript における Object は, ハッシュ変数として使われることもあり, これを検証できないのは致命的でしょう.<br />
とはいえ, オブジェクトがメソッドを持っていた場合, それを Ruby でどう表現するか, という問題もあり, 解決は難しいでしょう.</li>
</ul>
<p>上記の理由から, 実際に運用・保守していくのは難しいでしょう.</p>
<p>最近は HTML5 によるスマートフォンアプリ作りに挑戦しようとしているのですが, TDD/BDD のフレームワークに何を使うべきか, で迷っています.<br />
今のところは次作の簡単なフレームワークで検証していますが, さすがにずっと運用するわけにはいかないので, デファクトスタンダードなものが知りたいところです.<br />
いいのを知っている方は是非 <strong><a href="http://twitter.com/yuya_takeyama">@yuya_takeyama</a></strong> まで教えてください.</p>
<p>JavaScript におけるテスト技法については, 2011/03/08 (Tue) に <strong><a href="http://shibuyajs.org/articles/2011/02/28/test">Test.js</a></strong> というイベントでおもしろい話が聞けそうです.<br />
是非参加したいところですが, <a href="http://atnd.org/events/13389">ATND</a> への参加登録が遅くなったので絶望的な状態です&#8230;<br />
この記事を LT する発表者としての参加, なんてのはダメですよねぇ&#8230;<br />
Ust で我慢します.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/1132/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 上に IS01 の開発環境構築 #3 実機にデプロイ編</title>
		<link>http://blog.yuyat.jp/archives/802</link>
		<comments>http://blog.yuyat.jp/archives/802#comments</comments>
		<pubDate>Tue, 23 Nov 2010 12:45:28 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[IS01]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=802</guid>
		<description><![CDATA[#1 Android SDK 編 #2 PhoneGap 編 #3 実機にデプロイ編 はじめに 前回と前々回は、普通に Ubutu 上での Android アプリ開発環境構築についての記事となりましたが、今回はいよいよ  [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="/archives/719">#1 Android SDK 編</a></li>
<li><a href="/archives/769">#2 PhoneGap 編</a></li>
<li><strong><a href="/archives/802">#3 実機にデプロイ編</a></strong></li>
</ol>
<p><strong>はじめに</strong></p>
<p>前回と前々回は、普通に Ubutu 上での Android アプリ開発環境構築についての記事となりましたが、今回はいよいよ IS01 についてです。<br />
前回はエミュレータ上でアプリを実行してみましたが、今回は同じことを IS01 実機上にて行います。</p>
<p><strong>IS01 実機の準備</strong></p>
<p>まずは、 IS01 の設定をデバッグモードに変更します。<br />
デバッグモードといっても、通常のアプリを扱っている分には特に関係ないので、常に On でも問題なさそうです。</p>
<div id="attachment_803" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/802/attachment/001" rel="attachment wp-att-803"><img src="http://blog.yuyat.jp/wp-content/uploads/001-300x150.png" alt="IS01 メニュー" title="IS01 メニュー" width="300" height="150" class="size-medium wp-image-803" /></a><p class="wp-caption-text">メニューから「設定」を選択する</p></div>
<p>メニューから「設定」→「アプリケーション」へ進みます。</p>
<div id="attachment_807" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/802/attachment/002" rel="attachment wp-att-807"><img src="http://blog.yuyat.jp/wp-content/uploads/002-300x150.png" alt="Configuration Screen" title="Configuration Screen" width="300" height="150" class="size-medium wp-image-807" /></a><p class="wp-caption-text">「提供元不明のアプリ」にチェック</p></div>
<p>「提供元不明のアプリ」にチェックを入れたら、同じ画面の「開発」という項目を選択します。</p>
<div id="attachment_810" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/802/attachment/003" rel="attachment wp-att-810"><img src="http://blog.yuyat.jp/wp-content/uploads/003-300x150.png" alt="Debug Mode" title="Debug Mode" width="300" height="150" class="size-medium wp-image-810" /></a><p class="wp-caption-text">「USBデバッグ」にチェックを入れる</p></div>
<p>これで、 IS01 上の設定は完了です。</p>
<p><strong>Ubuntu PC の設定</strong></p>
<p>ここでは、 Android SDK の中に含まれる <strong>adb</strong> (Android Debug Bridge) というコマンドを使用します。<br />
Android SDK のインストールについては <strong><a href="/archives/719">Android SDK 編</a></strong>をご覧ください。</p>
<p>IS01 を USB で Ubuntu PC に接続します。<br />
特に設定を行なっていない状態だと、デバッグ用のデバイスとして上手く認識されません。</p>
<pre class="brush:bash">
$ adb devices
List of devices attached
????????????	no permissions
</pre>
<p>これを上手く認識させるには、 <strong>/etc/udev/rules.d/51-android.rules</strong> というテキストファイルを作成し、以下のように記述します。</p>
<pre class="brush:bash">SUBSYSTEM=="usb", SYSFS{idVendor}=="04dd", MODE="0666"</pre>
<p>ただし、上記は <strong>IS01 用の設定</strong>なので、ご注意ください。<br />
<strong>Ubuntu のバージョン</strong>や、 Android 端末の<strong>製造元</strong>によって書き換える必要があります。<br />
詳しくは以下のページをご覧ください。<br />
<strong><a href="http://developer.android.com/guide/developing/device.html">Developing on a Device</a></strong> Android Developers</p>
<p>念のため、全てのグループに読み込み権限を与えておきます。</p>
<pre class="brush:bash">sudo chmod a+r /etc/udev/rules.d/51-android.rules</pre>
<p>これらが完了したら、 USB 接続をやり直し、再び以下のコマンドで、デバッグ用デバイスが認識されているか確認します。</p>
<pre class="brush:bash">$ adb devices
List of devices attached
SSHEX060626	device</pre>
<p>上記のように出力されれば、設定は完了です。</p>
<p><strong>IS01 実機へのデプロイ・実行</strong></p>
<p>あとは、 PhoneGap 編で、エミュレータ上で実行したときと変わりません。<br />
ただし、エミュレータは終了して、デバッグ端末は IS01 1 台のみ、という状態にしておきます。</p>
<p>PhoneGap アプリのあるディレクトリへ移動して、以下のコマンドを実行します。</p>
<pre class="brush:bash">
$ ant debug install &#038;&#038; adb logcat
</pre>
<p>上手くいけば、エミュレータのときと同様、メニューにアプリが追加されます。</p>
<div id="attachment_829" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/802/attachment/004" rel="attachment wp-att-829"><img src="http://blog.yuyat.jp/wp-content/uploads/004-300x150.png" alt="example app is added." title="example app is added." width="300" height="150" class="size-medium wp-image-829" /></a><p class="wp-caption-text">メニューに example アプリが登録された</p></div>
<p>実行すると、以下のように表示されます。<br />
これも、エミュレータのときと同様ですね。</p>
<div id="attachment_830" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/802/attachment/005" rel="attachment wp-att-830"><img src="http://blog.yuyat.jp/wp-content/uploads/005-300x150.png" alt="Executed example app." title="Executed example app." width="300" height="150" class="size-medium wp-image-830" /></a><p class="wp-caption-text">example アプリを起動</p></div>
<p>UUID の部分だけ隠しています。</p>
<p>そして、縦バージョン。</p>
<div id="attachment_831" class="wp-caption aligncenter" style="width: 160px"><a href="http://blog.yuyat.jp/archives/802/attachment/006" rel="attachment wp-att-831"><img src="http://blog.yuyat.jp/wp-content/uploads/006-150x300.png" alt="Rotated Ver." title="Rotated Ver." width="150" height="300" class="size-medium wp-image-831" /></a><p class="wp-caption-text">縦にしてみる</p></div>
<p><strong>まとめ</strong></p>
<p>というわけで、全 3 回で、 Ubuntu 上に IS01 の開発環境を構築する方法について紹介してきました。<br />
ここまでできれば、あとは <strong>HTML</strong>, <strong>CSS</strong>, <strong>JavaScript</strong> を駆使して、アプリの開発が楽しめることでしょう。</p>
<p>このブログでも、引き続き Android アプリの開発について書いていく予定です。<br />
今回は <strong>PhoneGap</strong> の紹介になりましたが、使ってみておもしろければ <strong>Titanium</strong> 等の類似フレームワークについても紹介していければと思っています。</p>
<p>個人的には、今回初めて Android アプリをさわってみて、 HTML5 や CSS3 について興味を持てたことも面白かったです。<br />
HTML や CSS を書く機会が普段あまり無いので、いい機会になりました。</p>
<p>本格的なアプリを作る場合は、 Java や Objective-C でゴリゴリ書いていくのがいい場合もあるでしょう。<br />
しかし、スマートフォンアプリはほとんどがアイディアの勝負だと思うので、こういった間口の広い環境があるのは素晴らしいことだとおもいます。<br />
プログラムを書いたことがある人も無い人も、楽しくアプリ開発しましょう !</p>
<p><strong>See also</strong></p>
<ul>
<li><strong><a href="http://developer.android.com/guide/developing/device.html">Developing on a Device</a></strong> Android Developers<br />
Ubuntu PC の設定についてはこのページを参考にしました。</li>
<li><strong><a href="http://komugi.net/archives/2010/07/01184254.php">IS01 のスクリーンショットと壁紙</a></strong> コムギドットネット<br />
IS01 実機のスクリーンショットの撮影について参考にしました。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/802/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ubuntu 上に IS01 の開発環境構築 #2 PhoneGap 編</title>
		<link>http://blog.yuyat.jp/archives/769</link>
		<comments>http://blog.yuyat.jp/archives/769#comments</comments>
		<pubDate>Tue, 23 Nov 2010 05:32:35 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PhoneGap]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=769</guid>
		<description><![CDATA[#1 Android SDK 編 #2 PhoneGap 編 #3 実機にデプロイ編 PhoneGap とは PhoneGap は、 HTML/CSS/JavaScript でスマートフォンアプリを開発するためのフレーム [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="/archives/719">#1 Android SDK 編</a></li>
<li><strong><a href="/archives/769">#2 PhoneGap 編</a></strong></li>
<li><a href="/archives/802">#3 実機にデプロイ編</a></li>
</ol>
<p><strong>PhoneGap とは</strong></p>
<p><strong><a href="http://www.phonegap.com/">PhoneGap</a></strong> は、 HTML/CSS/JavaScript でスマートフォンアプリを開発するためのフレームワークです。複数のプラットフォームに対応しており、 Android だけでなく iPhone や iPad のアプリも開発できます。</p>
<p>PhoneGap が用意した API を、 JavaScript を通じて呼び出すことにより、より低レイヤの、位置情報やカメラにアクセスすることもできます。</p>
<p>この記事では、前回の <a href="/archives/719"><strong>#1 Android SDK 編</strong></a>から引き続き、 Ubuntu で Au の IS01 上で動作する Android アプリを構築する上での、環境構築について紹介します。<br />
今回は PhoneGap をインストールし、アプリをエミュレータ上で実行するところまでやります。</p>
<p><strong>必要パッケージ</strong></p>
<p>PhoneGap/Android をインストールする前に、以下のものが必要になります。</p>
<ul>
<li>Android SDK</li>
<li>Java JDK 1.5</li>
<li>Apache ANT</li>
<li>Ruby</li>
</ul>
<p>私の場合は、どれも既に入っていたようで、今回は特に作業を行っていないので、手順は省略します。<br />
Android SDK のインストールについては<a href="/archives/719">前回の記事</a>で紹介しています。<br />
他は、基本的に aptitude 等のパッケージマネージャで簡単にインストールできると思います。</p>
<p><strong>PhoneGap/Android のインストール</strong></p>
<p>GitHub から最新の安定版をダウンロードします。 2010 年 11 月 23 日現在は、 0.9.2 が最新のようです。</p>
<p><a href="https://github.com/phonegap/phonegap-android"><strong>phonegap&#8217;s phonegap-android at master &#8211; GitHub</strong></a></p>
<p>ダウンロードしたら、展開して、 /opt といったディレクトリにインストールしましょう。</p>
<pre class="brush:bash">
$ tar xvzf phonegap-phonegap-android-0.9.2-0-gf725404.tar.gz
$ sudo mv phonegap-phonegap-android-e1560e0/ /opt/phonegap-android
</pre>
<p><strong>~/.bashr</strong> 等に以下の行を足して、パスを通します。</p>
<pre class="brush:bash">
# PhoneGap/Android
export PATH=$PATH:/opt/phonegap-android/bin
</pre>
<p>保存したら、以下のコマンドで <strong>~/.bashrc</strong> を再読み込みし、反映させます。</p>
<pre class="brush:bash">
$ source ~/.bashrc
</pre>
<p>これで、 <strong>droidgap</strong> というコマンドが有効になっているはずです。</p>
<p><strong>スケルトンアプリの生成</strong></p>
<p>以下のコマンド、スケルトンが生成されます。ここで生成されるコードを元に開発していくことになります。</p>
<pre class="brush:bash">
$ droidgap gen example
</pre>
<p>example というディレクトリが生成され、中は以下のような構成になっているとおもいます。</p>
<pre class="brush:bash">
$ cd example
$ ls -l
合計 40
-rw-r--r-- 1 yuya yuya 2000 2010-11-23 13:54 AndroidManifest.xml
drwxr-xr-x 3 yuya yuya 4096 2010-11-23 13:54 assets
drwxr-xr-x 2 yuya yuya 4096 2010-11-23 13:54 bin
-rw-r--r-- 1 yuya yuya  697 2010-11-23 13:54 build.properties
-rw-r--r-- 1 yuya yuya 3202 2010-11-23 13:54 build.xml
-rw-r--r-- 1 yuya yuya  380 2010-11-23 13:54 default.properties
drwxr-xr-x 2 yuya yuya 4096 2010-11-23 13:54 libs
-rw-r--r-- 1 yuya yuya  419 2010-11-23 13:54 local.properties
drwxr-xr-x 7 yuya yuya 4096 2010-11-23 13:54 res
drwxr-xr-x 3 yuya yuya 4096 2010-11-23 13:54 src
</pre>
<p><strong>スケルトンアプリをエミュレータ上で起動する</strong></p>
<p>ターミナルをもうひとつ起動し、そちらで android コマンドから Android SDK and AVD Manager を起動し、エミュレータを起動します。<br />
ここの手順についても、<a href="/archives/719">前回の記事</a>で紹介した通りなので省略します。</p>
<p>エミュレータが起動したら、以下のコマンドで example アプリをビルドし、エミュレータ上で起動します。<br />
コマンドは example ディレクトリの中で実行してください。</p>
<pre class="brush:bash">$ ant debug install &#038;&#038; adb logcat</pre>
<p>上手くいけば、アプリがエミュレータ上にインストールされるとともに、デバッグログがターミナル上に流れます。</p>
<p>なお、このとき IS01 実機を USB で PC に接続していると上手くいかないことがあるようなので、一旦外しておいてください。<br />
実機上でのアプリの動作については、次回以降紹介する予定です。</p>
<p>アプリはメニューから起動できます。</p>
<div id="attachment_790" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/769/01-emulator-menu" rel="attachment wp-att-790"><img src="http://blog.yuyat.jp/wp-content/uploads/01-emulator-menu-300x202.png" alt="Android Emulator" title="Android Emulator" width="300" height="202" class="size-medium wp-image-790" /></a><p class="wp-caption-text">メニューを持ち上げます</p></div>
<div id="attachment_791" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/769/02-example-is-added-to-menu" rel="attachment wp-att-791"><img src="http://blog.yuyat.jp/wp-content/uploads/02-example-is-added-to-menu-300x202.png" alt="example app is added" title="example app is added" width="300" height="202" class="size-medium wp-image-791" /></a><p class="wp-caption-text">example アプリがメニューに追加されている</p></div>
<div id="attachment_792" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.yuyat.jp/archives/769/03-example-app" rel="attachment wp-att-792"><img src="http://blog.yuyat.jp/wp-content/uploads/03-example-app-300x202.png" alt="Executed example app." title="Executed example app." width="300" height="202" class="size-medium wp-image-792" /></a><p class="wp-caption-text">example アプリを起動する</p></div>
<p>ただし、これでは普通のアプリをインストールしたのと、違いがわからないと思うので、ソースを見てみましょう。<br />
アプリのソースは、 <strong>./assets/www/</strong> ディレクトリ内にあります。</p>
<pre class="brush:bash">
$ cd assets/www/
$ ls -l
合計 100
-rw-r--r-- 1 yuya yuya  4581 2010-11-23 13:54 index.html
-rw-r--r-- 1 yuya yuya  1612 2010-11-23 13:54 master.css
-rw-r--r-- 1 yuya yuya 87949 2010-11-23 13:54 phonegap.js
</pre>
<p>ごらんの通り、 HTML と CSS と JavaScript ですね !<br />
中身のソースも、ウェブアプリを作ったことのある人であれば、比較的馴染みのあるものだとおもいます。</p>
<p><strong>まとめ</strong></p>
<p>今回は、 PhoneGap/Android のインストール方法と、スケルトンを生成し、エミュレータ上で実行する方法について紹介しました。<br />
次回は IS01 実機上へのアプリのデプロイ・実行について紹介する予定です。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/769/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JavaScript ファイルの結合・難読化によるフロントエンド高速化</title>
		<link>http://blog.yuyat.jp/archives/486</link>
		<comments>http://blog.yuyat.jp/archives/486#comments</comments>
		<pubDate>Thu, 04 Nov 2010 17:33:55 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=486</guid>
		<description><![CDATA[このブログでは、記事中のプログラムの文法ハイライトに、 Syntax Highlighter and Code Colorizer for WordPress というプラグインを使用しています。 JavaScript と [...]]]></description>
			<content:encoded><![CDATA[<p>このブログでは、記事中のプログラムの文法ハイライトに、 <a href="http://wordpress.org/extend/plugins/syntax-highlighter-and-code-prettifier/"><strong><em>Syntax Highlighter and Code Colorizer for WordPress</em></strong></a> というプラグインを使用しています。 JavaScript と CSS で、プログラムを見易くしてくれる素敵なプラグインなのですが、 JavaScript ファイルだけで 1 度に 18 ものファイルを読むのが気になるところです。</p>
<p>外部のリソースが増えると、当然 HTTP リクエストも増え、ページ全体の表示時間に影響が出ます。</p>
<p>というわけで、以下のようなスクリプトを用意しました。</p>
<p><script src="https://gist.github.com/662740.js?file=syntax-highlighter-minimizer.rb"></script></p>
<p><strong>使い方</strong></p>
<p>まずは、上記 Ruby スクリプトを syntax-highlighter-minimizer.rb といった適当な名前で保存します。</p>
<p>このスクリプトの動作には、 <strong><em>JSMin</em></strong> という Rubygems が必要なので、インストールします。</p>
<pre class="brush:bash">$ gem install jsmin --no-rdoc --no-ri</pre>
<p>スクリプトは以下のように使用します。</p>
<pre class="brush:bash">$ ruby syntax-highlighter-minimizer.rb /path/to/syntax-highlighter-and-code-prettifier/script</pre>
<p>プログラムの引数として、 <strong>sh***.js といったファイルの含まれるディレクトリのパス</strong>を渡して実行します。すると、ディレクトリ内に以下のようなファイルが保存されます。</p>
<ul>
<li><strong>syntax-highlighter-all.js</strong> &#8230; sh***.js をすべて結合したもの</li>
<li><strong>syntax-highlighter-all-min.js</strong> &#8230; ***.js をすべて結合し、難読化したもの</li>
</ul>
<p>仕上げとして、 JavaScript ファイルの読み込み部分を書き換え、ファイルを結合・難読化したものと置き換えます。</p>
<p><em>./wp-content/plugins/syntax-highlighter-and-code-prettifier/syntax-highlighter.php</em></p>
<p><script src="https://gist.github.com/662740.js?file=syntax-highlighter.php.diff"></script></p>
<p>18 もあった JavaScript ファイルがひとつにまとまりました !</p>
<p><strong>難読化とは</strong></p>
<p>文字通りに言えば、プログラムを読みにくくすることですが、実際は<strong>ソースコードの圧縮</strong>が目的です。インデント等を極力少なくすることで、圧縮されます。</p>
<p><strong>どれぐらいの効果があるか</strong></p>
<p>以下のようなページを作って測定してみました。</p>
<ul>
<li><a href="/test/20101105/default.html">default.html</a> &#8230; 元の 18 の JavaScript が読み込まれる</li>
<li><a href="/test/20101105/all.html">all.html</a> &#8230; 18 の JavaScript を 1 つのファイルに結合したものが読み込まれる</li>
<li><a href="/test/20101105/all-min.html">all-min.html</a> &#8230; 1 つのファイルに結合したのち、難読化したものが読み込まれる</li>
</ul>
<p>いずれも、 script タグにより JavaScript が読み込まれるだけのシンプルなページです。 FireFox で Ctrl + F5 の強制更新で、 onload イベントの発生までの時間を計測しています。</p>
<table style="text-align:center;">
<tbody>
<tr>
<th style="width: 10%;"></th>
<th style="width: 30%;">default.html</th>
<th style="width: 30%;">all.html</th>
<th style="width: 30%;">all-min.html</th>
</tr>
<tr>
<td>1</td>
<td>379ms</td>
<td>140ms</td>
<td>180ms</td>
</tr>
<tr>
<td>2</td>
<td>375ms</td>
<td>148ms</td>
<td>168ms</td>
</tr>
<tr>
<td>3</td>
<td>556ms</td>
<td>131ms</td>
<td>133ms</td>
</tr>
<tr>
<td>4</td>
<td>365ms</td>
<td>135ms</td>
<td>124ms</td>
</tr>
<tr>
<td>5</td>
<td>370ms</td>
<td>146ms</td>
<td>137ms</td>
</tr>
<tr>
<td>6</td>
<td>363ms</td>
<td>128ms</td>
<td>133ms</td>
</tr>
<tr>
<td>7</td>
<td>370ms</td>
<td>257ms</td>
<td>132ms</td>
</tr>
<tr>
<td>8</td>
<td>397ms</td>
<td>122ms</td>
<td>133ms</td>
</tr>
<tr>
<td>9</td>
<td>411ms</td>
<td>127ms</td>
<td>136ms</td>
</tr>
<tr>
<td>10</td>
<td>362ms</td>
<td>135ms</td>
<td>135ms</td>
</tr>
<tr>
<th>Avg.</th>
<td>394.8ms</td>
<td>146.9ms</td>
<td style="color: #f44;"><strong>141.1ms</strong></td>
</tr>
</tbody>
</table>
<p>難読化による効果は誤差程度に止まりましたが、 JavaScript ファイルをまとめることは、絶大な効果があるようです。今回の例でいえば、 <strong>2.8 倍近い高速化</strong>が実現できました。</p>
<p>ただし、実際のウェブサイトは、 JavaScript 以外にもたくさんの要素を含み、キャッシュ等の要因も絡むため、ここまでのインパクトは無いと思いますが、ページの表示時間が気になるときは、是非検討してみるべきでしょう。</p>
<p><strong>今後の予定</strong></p>
<p>今回は特定のプラグインに標的を絞りましたが、 WordPress といった CMS を使用する場合、プラグインで JavaScript や CSS の数がもの凄いことになっていた ! というのはよくあると思います。それらを 1 つ 1 つ潰していくことで、案外バカにできない効果が期待できそうです。</p>
<p>あと、 JavaScript ファイルを減らそう ! とかいいながら、この記事には GitHub の Gist が 2 つも貼り付けられています。これらは JavaScript の外部リソースによるものなので、ページ全体の読み込み時間に影響します。ページの読み込み時に読み込むのではなく、「このコードは読んでみたいな」と思ってクリックするまで、読み込みを遅延させる、という仕組みもアリかもしれません。</p>
<p><strong>参考文献</strong></p>
<p><span class="isbn_anchor"><a href="http://www.amazon.co.jp/o/ASIN/487311361X/yuyat-22/"><img src="http://ecx.images-amazon.com/images/I/51hIDIWHmYL._SL160_.jpg" />ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール</a></span></p>
<p>Yahoo ! のフロントエンド最適化チームによるノウハウ集で、 JavaScript の結合・難読化についてはほとんどこの書籍に書いてあります。</p>
<p>その他にも様々なテクニックが紹介されていますが、その中でも特に敷居が低いのが、この JavaScript についての最適化です。</p>
<p>是非試してみてはいかがでしょうか。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/486/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl でも JavaScript っぽくクロージャが作れるんですね</title>
		<link>http://blog.yuyat.jp/archives/441</link>
		<comments>http://blog.yuyat.jp/archives/441#comments</comments>
		<pubDate>Sun, 17 Oct 2010 07:29:53 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Closure]]></category>
		<category><![CDATA[Lambda]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=441</guid>
		<description><![CDATA[JavaScript ではよくある、こういう書き方。 一応説明すると、これは実行時に外側の無名関数を実行します。外側の無名関数は返り値として、内側の無名関数を返し、変数 counter には内側の無名関数が代入されます。 [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript ではよくある、こういう書き方。</p>
<p><script src="http://gist.github.com/630586.js?file=counter.js"></script></p>
<p>一応説明すると、これは実行時に外側の無名関数を実行します。外側の無名関数は返り値として、内側の無名関数を返し、変数 counter には内側の無名関数が代入されます。</p>
<p>これの何が嬉しいのか。</p>
<ul>
<li>counter 関数が内部に持っている変数 i は隠蔽されており、外から変更できない。</li>
<li>グローバル空間の汚染は counter 1 つだけ。</li>
</ul>
<p>といったところでしょうか。とにかく、 JavaScript 脳の人はこういう感じのコードをよく書いている気がします。 JavaScript にはオブジェクト指向によくある protected や private といったアクセスレベルを制御する機能が無いため、これの応用で内部の変数やメソッドを隠蔽することが多いです。 Prototype や jQuery でもそういった使い方がされています。</p>
<p>このように、 JavaScript では無名関数の中にスコープを閉じ込めることができ、これを<strong>クロージャ</strong>と呼びます。</p>
<p>で、最近久しぶりに勉強している Perl 。 <a href="http://plackperl.org/">Plack</a> のコードを読んでいる中で、 <strong>Perl にも無名関数とクロージャがある</strong>ということを知ったので、試してみました。</p>
<p><script src="http://gist.github.com/630586.js?file=counter.pl"></script></p>
<p>上部のおまじない的なものを除けば、やってることは本質的に何も変わりません。</p>
<p>ついでに Ruby も。これもやっていることは特に変わらないと思います。</p>
<p><script src="http://gist.github.com/630586.js?file=counter.rb"></script></p>
<p>Python にも無名関数 (ラムダ) はあるので、同じようなことができそうな気がしたのですが、うまくいかず、代わりにこんな書き方に。</p>
<p><script src="http://gist.github.com/630586.js?file=counter.py"></script></p>
<p>これはクロージャではなく、ジェネレータという機能を使っています。内部の変数が隠蔽されており、名前空間の汚染も 1 つだけですが、最初は関数だった counter にジェネレータをぶち込むというのは、お行儀的にはよくないかもしれません。</p>
<p>で、 PHP でも 5.3 からは無名関数・クロージャが使えるようになったので、試してみたのですが、以下の JavaScript 的な記述では parse error となりました &#8230;</p>
<p><script src="http://gist.github.com/630586.js?file=counter_error.php"></script></p>
<p>以下のように書き換えると動きますが、これでは名前空間の汚染が 2 つです。</p>
<p><script src="http://gist.github.com/630586.js?file=counter.php"></script></p>
<p>そして、何かもう方向を見失っている例。</p>
<p><script src="http://gist.github.com/630586.js?file=counter_tostring.php"></script></p>
<p>変数の名前空間汚染は 1 つだけど、クラス名の名前空間まで汚染してしまっている上、返り値が文字列になっています。 (__toString はそのように定義しないといけないため)</p>
<p>そして、一応数値を返すようにしたものが以下。</p>
<p><script src="http://gist.github.com/630586.js?file=counter_invoke.php"></script></p>
<p>なんか、 JavaScript と Perl の話だったはずが、暗に PHP を Dis る結果になってしまったので、今日はこの辺で。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/441/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JavaScript で private なインスタンス変数 (のようなもの) を作る</title>
		<link>http://blog.yuyat.jp/archives/301</link>
		<comments>http://blog.yuyat.jp/archives/301#comments</comments>
		<pubDate>Tue, 13 Apr 2010 05:13:44 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=301</guid>
		<description><![CDATA[通勤電車の中で思いついたコードを、昼休みを利用して書いてみました。動いたので公開。ただし、バッドノウハウなので要注意。 解説 まず、クロージャを利用して、外からは見えない privateNameSpace という名前空間 [...]]]></description>
			<content:encoded><![CDATA[<p>通勤電車の中で思いついたコードを、昼休みを利用して書いてみました。動いたので公開。ただし、バッドノウハウなので要注意。</p>
<p><script src="http://gist.github.com/364324.js"></script></p>
<p><strong>解説</strong></p>
<p>まず、<strong>クロージャ</strong>を利用して、外からは見えない privateNameSpace という名前空間を作ります。この privateNameSpace 自体は、言わば <strong>private static</strong> なものなので、Dog オブジェクトが個別に持つものではなく、Dog クラスに紐づく (ように見える) 空間です。</p>
<p>これを、各インスタンス毎に分けて使えるよう、Dog コンストラクタで objectId というメンバ (これは public) を作っています。objectId は、ミリ秒単位の時間と、乱数を文字列として結合したもので、<strong>およそユニークである</strong>ことが期待されています。とはいえ、理論上は衝突の可能性もあり得るのですが・・・。</p>
<p>この objectId をキーに、privateNameSpace の中に、連想配列オブジェクトを作れば、インスタンスごとに private な名前空間を持つことができる、というわけです。</p>
<p>2 番目のコードを動かしてみると、何となくそれらしく動いていることが確認できます。</p>
<p>ただ、大きな問題は、<strong>objectId を乗っ取ることができてしまう</strong>ということです。3 番目のコードのようにすることで、もともとは pochi オブジェクトだったものが、あたかも taro オブジェクトであるかのように振舞うようになってしまいます。</p>
<p><strong>まとめ</strong></p>
<p>上記の問題の他にも、メンバの取得のための記述が煩雑なところも大きな問題と言えます。もう少し抽象化できれば書きやすくなるかもしれませんが、いずれにせよ、実用的な方法では無いでしょう。</p>
<p>似たようなことを実現するためのノウハウはネット上にいろいろ転がっているようなので、そちらも読んでみたいと思った次第です。</p>
<p><strong>あとで読む</strong></p>
<ul>
<li><a href="http://www.crockford.com/javascript/private.html">Private Members in JavaScript</a></li>
<li><a href="http://d.hatena.ne.jp/llamerada/20050903/1125720037">JavaScript で private/public の実現</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/301/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript でもマルコフ連鎖やってみた</title>
		<link>http://blog.yuyat.jp/archives/291</link>
		<comments>http://blog.yuyat.jp/archives/291#comments</comments>
		<pubDate>Mon, 22 Mar 2010 09:49:38 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Markov Chain]]></category>
		<category><![CDATA[N-gram]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=291</guid>
		<description><![CDATA[Markov Chain in JavaScript 2011-05-03 追記: 消えていたので別 URL にて作りなおしました. Twitter につぶやく機能もつけてみたのでお試しあれ。 オブジェクト指向な上に、G [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://lab.yuyat.jp/markov-chain/">Markov Chain in JavaScript</a><br />
2011-05-03 追記: 消えていたので別 URL にて作りなおしました.<br />
<del datetime="2011-05-03T02:24:18+00:00">Twitter につぶやく機能もつけてみたのでお試しあれ。</del></p>
<p>オブジェクト指向な上に、GUI アプリケーションも簡単に作れてしまう。JavaScript はやっぱり楽しいですね。</p>
<p>実装としては、前のエントリーの <a href="archives/282">Ruby のもの</a>と特に変わりません。Ruby のコードを見ながら移植してほぼ終わり。ただ、Ruby 版では「改行コードをすっ飛ばす」仕様になっていたのを、すっ飛ばさないことにしています。</p>
<p>前のエントリーに載せた、<strong>『口辺筋肉感覚による叙情的作品』</strong>を、Chain length を 2 として実行すると、どっちが入力でどっちが出力なのか見分けがつかなくておもしろい。さて、次のうちどれが本物でしょうか？</p>
<p><strong>A</strong></p>
<blockquote><p>
ポポ</p>
<p>ヌルヌルヌルモナラミ</p>
<p>ヌルモモヌム</p>
<p>ギレッチョ</p>
<p>ヌム</p>
<p>ヌルヌルモモヌムヌムモナラミ</p>
<p>ギレッチョ</p>
<p>ズルマッチョ</p>
<p>ヌルモモヌム</p>
<p>ポエ</p>
<p>ポエ</p>
<p>ヌム</p>
<p>ヌムヌム</p>
<p>ギレッチョ</p>
<p>ズルマッチョ</p>
<p>ヌルヌルモモヌムヌム</p>
<p>ヌルモモヌム</p>
<p>ヌルモモヌムモナラミ</p>
<p>ヌルヌルヌルモモヌムモナラミ</p>
<p>ギレッチョ</p>
<p>ヌルヌルモモヌムヌム</p>
<p>ポエ</p>
<p>ズルマッチョ</p>
<p>ヌルヌルモモヌムモナラミ</p>
<p>ヌムヌムモナラミ</p>
<p>ポエ</p>
<p>鈴木志郎康作『口辺筋肉感覚による叙情的作品』より
</p></blockquote>
<p><strong>B</strong></p>
<blockquote><p>
ポポ</p>
<p>ズルマッチョ</p>
<p>ヌルモモヌムモナラミ</p>
<p>ヌルヌルヌルヌルヌルヌルヌルヌルヌルモモヌムヌムモナラミ</p>
<p>ポエ</p>
<p>ギレッチョ</p>
<p>ヌルヌルモモヌムモナラミ</p>
<p>ヌルモモヌムモナラミ</p>
<p>ギレッチョ</p>
<p>ヌルモナラミ</p>
<p>ギレッチョ</p>
<p>ポエ</p>
<p>ヌルモモヌム</p>
<p>ズルマッチョ</p>
<p>ヌルモナラミ</p>
<p>ヌルヌルモナラミ</p>
<p>鈴木志郎康作『口辺筋肉感覚による叙情的作品』より
</p></blockquote>
<p><strong>C</strong></p>
<blockquote><p>
ポポ</p>
<p>ヌルヌルモモヌム</p>
<p>ヌルヌルモモヌムヌムヌムモナラミ</p>
<p>鈴木志郎康作『口辺筋肉感覚による叙情的作品』より
</p></blockquote>
<p><strong>D</strong></p>
<blockquote><p>
ポポ</p>
<p>ヌムヌムモナラミ</p>
<p>ヌルヌルモモヌム</p>
<p>ギレッチョ</p>
<p>ズルマッチョ</p>
<p>ヌルヌルモナラミ</p>
<p>ヌルヌルモモヌム</p>
<p>ズルマッチョ</p>
<p>ポエ</p>
<p>鈴木志郎康作『口辺筋肉感覚による叙情的作品』より
</p></blockquote>
<p><strong>E</strong></p>
<blockquote><p>
ポポ</p>
<p>鈴木志郎康作『口辺筋肉感覚による叙情的作品』より
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/291/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>メタプログラミングで PHP をもっとオブジェクト指向に</title>
		<link>http://blog.yuyat.jp/archives/197</link>
		<comments>http://blog.yuyat.jp/archives/197#comments</comments>
		<pubDate>Sat, 27 Feb 2010 04:30:17 +0000</pubDate>
		<dc:creator>yuya</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[OOP]]></category>

		<guid isPermaLink="false">http://blog.yuyat.jp/?p=197</guid>
		<description><![CDATA[PHP はブジェクト指向言語です。ですが、Ruby や JavaScript のような、より純度の高いオブジェクト指向言語とは違って、以下のようなことはできません。 puts ['foo', 'bar', 'baz']. [...]]]></description>
			<content:encoded><![CDATA[<p>PHP はブジェクト指向言語です。ですが、Ruby や JavaScript のような、より純度の高いオブジェクト指向言語とは違って、以下のようなことはできません。</p>
<pre class="brush:ruby">
puts ['foo', 'bar', 'baz'].join(',').upcase
# => FOO,BAR,BAZ
</pre>
<pre class="brush:js">
print(['foo', 'bar', 'baz'].join(',').toUpperCase());
// => FOO,BAR,BAZ
</pre>
<p>これは、Ruby や JavaScript において、配列や文字列がオブジェクトとして扱われ、メソッドを持つことができるからこそできる書き方です。</p>
<p>同じようなことを PHP でやろうとすると、以下のようなおぞましいことになってしまいます。</p>
<pre class="brush:php">
echo strtoupper(join(array('foo', 'bar', 'baz'), ','));
// => FOO,BAR,BAZ
</pre>
<p>Ruby や JavaScript のような、メソッドチェインを使った書き方と、PHP のような関数でラップしていく書き方で決定的に違うのは、やはり可読性でしょう。プログラムに書いた順番通りに処理されるので、ほとんどの人にとって、メソッドチェインの方が可読的であると考えられます。</p>
<p>そこで、PHP でも組み込み関数でメソッドチェインができるよう、以下のようなクラスを用意します。</p>
<pre class="brush:php">
class MyObject
{
    private $_selfMember;

    public function __construct($param)
    {
        $this->_selfMember = $param;
    }

    public function __call($name, $args)
    {
        $new_args = array_merge(
            array($this->_getSelfMember()),
            $args
        );
        return new self(call_user_func_array($name, $new_args));
    }

    public function _getSelfMember()
    {
        return $this->_selfMember;
    }

    public function __toString()
    {
        return print_r($this->_selfMember, true);
    }
}
</pre>
<p>このクラスを使うと、以下のようなコードが書けるようになります。</p>
<pre class="brush:php">
$obj = new MyObject(array('foo', 'bar', 'baz'));
echo $obj->join(',')->strtoupper();
// => FOO,BAR,BAZ
</pre>
<p>PHP の文法の制約上、ここまでが限界ですが、何とかそれらしくなりました。join も strtoupper も PHP の組み込み関数ですが、あたかもオブジェクトのメソッドのように呼び出すことができています。</p>
<p>この実装を可能にしているのが、PHP の<strong>マジックメソッド</strong>と呼ばれる、特殊なメソッドです。</p>
<p><strong>__call</strong> メソッドは、メソッドが存在しない時に実行されます。引数として、実行しようとしたメソッドの名前と、その引数を受けるので、call_user_func_array に渡して、関数を実行しています。Ruby でいうと method_missing メソッドに相当します。</p>
<p>そして、上記のコードで、__call メソッドの返り値は、MyObject を new した新たなオブジェクトになっているので、このままでは、これを echo することはできません。</p>
<p>ここで、<strong>__toString</strong> を使うと、オブジェクトを文字列として出力するときの形式を定義できます。ここでは print_r を使っています。Ruby でいうと、to_s メソッドに相当します。 (ここでの動作は inspect メソッド的ですが)</p>
<p>ただし、この MyObject クラスは、あくまでも簡易的なものなので、存在しない関数を実行しようとしたときのエラー処理等をしていません。また、内部で実行する関数への、引数の渡し方によっては、うまく動作しません。例えば、explode や preg_replace など。</p>
<p>いろいろと問題点があって、MyObject 自信は使い物にはなりませんが、マジックメソッドによるメタプログラミングは、PHP によるプログラムの書き方の可能性を、大きく広げていると言えるでしょう。</p>
<p>だからと言って、チーム開発でこのようなコードを書くと、自分以外のメンバーに混乱を招くことになるので、安易に使うのはオススメできませんが・・・。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yuyat.jp/archives/197/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

