<?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>ひげろぐ</title>
	<atom:link href="http://brass.to/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://brass.to/blog</link>
	<description>技術者として仕事人としての思うところや覚え書きやらです</description>
	<lastBuildDate>Sun, 29 Aug 2010 03:22:29 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>RubyKaigi2010の感想</title>
		<link>http://brass.to/blog/rubykaigi2010.html</link>
		<comments>http://brass.to/blog/rubykaigi2010.html#comments</comments>
		<pubDate>Sun, 29 Aug 2010 03:22:29 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[イベント]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=597</guid>
		<description><![CDATA[2日目だけ行って来ました。
実はRubyKaigiには今回初めて行ってみたのだけれど、お祭りみたいで楽しかった。
これは来年もまた是非行きたいなあと思いました。
以下とりとめもなく。
超絶技巧 Ruby プログラミング
 [...]]]></description>
			<content:encoded><![CDATA[<p>2日目だけ行って来ました。</p>
<p>実はRubyKaigiには今回初めて行ってみたのだけれど、お祭りみたいで楽しかった。<br />
これは来年もまた是非行きたいなあと思いました。</p>
<p>以下とりとめもなく。</p>
<h5>超絶技巧 Ruby プログラミング</h5>
<p>アホなことをまじめにやっている姿が感動的。<br />
最初の参加セッションでいきなりエンドロールを見せられてしまった。（個人スポンサーだったので自分の名前も出た！）</p>
<p>ニコ動に上がっていたので暇な時間に是非見てみて欲しい。息抜きの時間に最適です。</p>
<ul>
<li><a href="http://www.nicovideo.jp/watch/sm11914507">[rk10][28M03] 超絶技巧 Ruby プログラミング‐ニコニコ動画(9)</a></li>
</ul>
<h5>Vim</h5>
<p>セッションをやっている201-Aに行ったら超満員御礼状態。<br />
入り口から人があふれていて立ち見状態だった。<br />
というわけで入るのは断念。</p>
<p>隣でやっていたEmacsの方はだいぶ余裕があるようだった。<br />
RubyistはVim使いが多いのかな？</p>
<h5>Cucumberハンズオン</h5>
<p>一番楽しみにしていたセッションだったのだけれど、環境構築が出来ていなくて＼(^o^)／</p>
<p>当日出発前にいろいろ入れて大丈夫と思っていたら、Ruby自体がopensslやらいろいろと無効な状態でのインストールになっていて、いざ動かそうとしたらRailsがまともに動かなかったという。<br />
これは必要なgemが入らないとかそんなチャチなもんじゃねえ（ｒｙ</p>
<p>Cucumberを動かすための環境構築のサポートもしてくれていたけれど、なんというそういうサポート以前の問題だこれは。<br />
そんなわけで動かすのはあきらめて、コードの書き写しだけひっそりとやってました。</p>
<p>apt-getで必要なパッケージを入れてRubyの再構築というのも並行してやっていたのだけれど、会場のWifiも熾烈な帯域の奪い合いが実感されるほどのつながったりつながらなかったりっぷりで、終わったのがちょうどセッション終了と同時でしたとさ。どっどはらい。</p>
<h5>ライトニングトークス</h5>
<p>制限時間内に終えるとKY呼ばわりされるおかしなLTでした。<br />
何が言いたいかというと、ドラ娘かわいかったです。</p>
<p>ネタ的にはGoogleWave本の人が全部持って行ったかんじ。<br />
本が刷り上がった日に開発終了のお知らせとか涙なしには聞けない。<br />
X-Ruby、O-Ruby、F-Rubyも最高でしたｗ</p>
<p>そのほかで個人的に刺さったのはMessagePack、Almanac for Ruby、Lingoあたり。<br />
折を見て追いかけてみようかと。</p>
<p>それから達人出版会の今後には期待。<br />
売り上げの配分とか金銭的な面が難しそうだけれど、うまいことできれば相当面白いことになりそう。</p>
<h5>懇親会</h5>
<p>人見知り的にはある意味大変な場所ではあるが何人かと話せてそこそこ有意義な時間を過ごせた。</p>
<p>会ってみたい人の名前を書く、というのはいきなり振られたのですでにMatzと書きました。<br />
すみません。すでに帰途についていること承知でした。<br />
でも生Matzを見たことがないのでいつか実際会ってみたいです。</p>
<h5>トートバッグ</h5>
<p>思いもかけずもらえたのでうれしかった。<br />
作りもしっかりしていて便利そうなので常用させてもらいます！</p>
<h5>交通アクセス</h5>
<p>横浜の片田舎からだとつくばまで片道3時間というのはさすがに遠かった。<br />
これは連日参加するなら泊まり必須ですねー。</p>
<p>来年はどこでやるのか分からないけれど宿泊も要検討事項としておく。</p>
<h5>iRubyKaigi</h5>
<p>出発直前に入れてみたが、自分の参加したいセッションを整理するのにとても便利だった。<br />
作者様ありがとうございます。</p>
<ul>
<li><a href="http://itosoft.blogspot.com/2010/08/irubykaigi-2010ready-for-sale.html">THE BEAT GOES ON.: iRubyKaigi 2010がReady for Saleになりました</a></li>
</ul>
<h5>すてきな会場の雰囲気</h5>
<p>心浮き立つような祭りの空気があった。<br />
と言っても別に騒がしいわけではないんだけど、なんか良い雰囲気だった。</p>
<p>廊下にいくつか机といすが並べられていて、作業スペースとしてもいいかんじに見えた。<br />
参加したいセッションがなくても、思い思いに作業しつつ時間をつぶせるかんじ。</p>
<p>ぶらっと好きなときにやってきて、ぶらっと好きなときに帰れるような気楽な空気でもありました。<br />
文化祭とかが感覚としては近い？</p>
<p>スタッフさんたちの対応も気持ちよくてよかったです。<br />
運営ほんとうにお疲れ様でした。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/rubykaigi2010.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iPad開発を始めたい人へ</title>
		<link>http://brass.to/blog/beginning-ipad-development.html</link>
		<comments>http://brass.to/blog/beginning-ipad-development.html#comments</comments>
		<pubDate>Wed, 25 Aug 2010 02:31:36 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone開発]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=588</guid>
		<description><![CDATA[周りにiPad開発してみたい！という開発者がいくらかいるのでひとつ。
言語問わずある程度UIを持ったアプリ開発の経験のある開発者向けに。
しかしながらすでにけっこうためになるまとめがあるので主にそちらを参照。

知識ゼロ [...]]]></description>
			<content:encoded><![CDATA[<p>周りにiPad開発してみたい！という開発者がいくらかいるのでひとつ。<br />
言語問わずある程度UIを持ったアプリ開発の経験のある開発者向けに。</p>
<p>しかしながらすでにけっこうためになるまとめがあるので主にそちらを参照。</p>
<ul>
<li><a href="http://d.hatena.ne.jp/glass-_-onion/20100802/1280758789">知識ゼロからはじめるiPhoneアプリ開発 &#8211; A Day In The Life</a></li>
</ul>
<p>と、丸投げ。<br />
あとは思うところをちょっとだけちょっとだけ。</p>
<h4>開発の準備</h4>
<p>iPhone Developer Programへの登録が必要。<br />
10800円ケチケチせずに払う。</p>
<p>登録時日本語使わない。<br />
使うと修正のためにオペレーターとのメール経由でのやりとり数週間コースに突入。</p>
<p>IDEはおとなしくXCodeで。補完がないと無理。</p>
<h4>SDKをひとつのフレームワークとしてとらえる</h4>
<p>フレームワークの提供する枠組みに沿って開発すれば、ちょっとしたユーティリティ系のアプリであれば割とさくっと作れる。<br />
よくスクリプトを組んだ経験のないデザイナーの人などが「簡単に作れちゃいました」と言っているのを聞くのもそのため。</p>
<p>逆にフレームワークの文脈を理解するのを億劫がってオレオレに走ると苦難の道が待っている。<br />
待っていましたとも。車輪の再発明どころじゃねえ。</p>
<p>基本を理解するために必要そうなドキュメントは全部目を通す。<br />
とりあえず以下の「一般」にカテゴライズされている物は必読。</p>
<ul>
<li><a href="http://developer.apple.com/jp/iphone/library/japanese.html">iPhone Dev Center 日本語ドキュメント</a></li>
</ul>
<h4>Interface Builderは使う？使わない？</h4>
<p>最初はどっちでも。</p>
<p>使う場合。<br />
フレームワークとObjective-Cの学習コストに加えてInterface Builderとの連携の仕方を覚えるのはちょっとしんどい。</p>
<p>使わない場合。<br />
とはいえUIに部品を追加するたびにリファレンスと首っ引きになってたら開発が遅々として進まなくてしんどい。</p>
<p>いずれにしろ最初はしんどいのかと思われる。<br />
最初はサンプルに沿って何かを作ってみると言うところからスタートすると思うので、そのサンプルに追随すればいいのではないかと。</p>
<p>コードによるUIの構築は基本addSubviewでUIViewオブジェクトをレイヤーのノリで重ねて行くだけ。<br />
ナビゲーションバーにボタンを表示するなどの、関連性のあるオブジェクトの設置に関してはその処理をラッピングしてくれるメソッドが準備されている。</p>
<p>なので、コード書くのに慣れたらInterface Builder使わない方がむしろ簡単でよいと思う。</p>
<h4>メモリ周りはしっかりと理解を</h4>
<p>iOS上では残念ながらガベージコレクションが使えないので、リファレンスカウンタでオブジェクトの解放を管理する。<br />
どのタイミングでリファレンスカウンタが増減するかをきちんと知っておかないと、メモリリークしまくったり、逆にまだ使っているオブジェクトを解放して往生する。</p>
<p>ちなみにObjective-C 2.0にはガベージコレクションの仕組みがある。<br />
iOSで使えなくしているのはハード性能の制約のため。<br />
とはいえiOS自体が徐々に下位機種切り捨ての方向に向かっているので、いずれは使えるようにならないものかと期待してしまう。</p>
<h4>その他</h4>
<p>過去記事。</p>
<ul>
<li><a href="http://brass.to/blog/tag/iphone%E9%96%8B%E7%99%BA">iPhone開発 &#8211; ひげろぐ</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/beginning-ipad-development.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>最近のiPadの使い道</title>
		<link>http://brass.to/blog/%e6%9c%80%e8%bf%91%e3%81%aeipad%e3%81%ae%e4%bd%bf%e3%81%84%e9%81%93.html</link>
		<comments>http://brass.to/blog/%e6%9c%80%e8%bf%91%e3%81%aeipad%e3%81%ae%e4%bd%bf%e3%81%84%e9%81%93.html#comments</comments>
		<pubDate>Wed, 18 Aug 2010 13:12:37 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iPad]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=586</guid>
		<description><![CDATA[iPad買っては見たが飽きてすっかり使わなくなった、なんて声もあるようだけれど、発売とほぼ同時に手に入れて以来、自分の生活の中では日用品として定着している。
最近の主な用途は以下のようなもの。
* 電子書籍（GoodRe [...]]]></description>
			<content:encoded><![CDATA[<p>iPad買っては見たが飽きてすっかり使わなくなった、なんて声もあるようだけれど、発売とほぼ同時に手に入れて以来、自分の生活の中では日用品として定着している。</p>
<p>最近の主な用途は以下のようなもの。</p>
<p>* 電子書籍（GoodReader）<br />
* 手書きメモ（neuNotes）<br />
* プロトタイピング（neuNotes）<br />
* 天気予報（そら案内 for iPad）<br />
* フォトフレーム<br />
* 時計<br />
* ごろ寝インターネッツ<br />
* 開発テスト機</p>
<p>中でも頻度が高いのは電子書籍、メモ、プロトタイピングあたり。</p>
<p>特にやっぱり電子書籍が便利すぎる。<br />
GoodReaderも横スワイプでのページ送りにいつの間にか対応していたので、普通の本のページをめくるようにすいすい読んでいけるようになった。<br />
あとは細かい字も読みやすくなるように、RetinaディスプレイのiPad登場が待ち望まれる。</p>
<p>メモやUIのプロトタイピングにneuNotesが大活躍。<br />
手書きメモはほかに有料のものも試してみたりしたけれど、フリーのneuNotesが今のところ一番使いやすい。<br />
紙とペンはすっかり使わなくなった。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/%e6%9c%80%e8%bf%91%e3%81%aeipad%e3%81%ae%e4%bd%bf%e3%81%84%e9%81%93.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ウェブアプリケーションで必ず5秒以内に応答を返す方法</title>
		<link>http://brass.to/blog/in-5sec-response.html</link>
		<comments>http://brass.to/blog/in-5sec-response.html#comments</comments>
		<pubDate>Thu, 12 Aug 2010 01:59:09 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[インフラ]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=581</guid>
		<description><![CDATA[ソーシャルアプリのアプリケーションサーバーは5秒とか10秒以内にリクエストを返さないとプラットフォームの中継サーバーからタイムアウト扱いにされる。
で、一定時間内に一定数以上のタイムアウトが起こると新規ユーザー登録停止な [...]]]></description>
			<content:encoded><![CDATA[<p>ソーシャルアプリのアプリケーションサーバーは5秒とか10秒以内にリクエストを返さないとプラットフォームの中継サーバーからタイムアウト扱いにされる。<br />
で、一定時間内に一定数以上のタイムアウトが起こると新規ユーザー登録停止などのペナルティをプラットフォームから受けるようになっている。</p>
<p>これはとても痛い。<br />
なので必ず規定時間内に応答を返したいのだがどうしたらよいのか。</p>
<p>答えとしてはロードバランサーを利用して実現することができる。<br />
要はバックエンドが一定時間内に応答を返してこなかった場合にロードバランサーが代わりに応答を返すというやり方。</p>
<p>ロードバランサー自身が5秒以内に応答を返せないくらいにいっぱいいっぱいになる可能性もあるが、そんなことは滅多にないだろう。</p>
<h4>Apacheのmod_proxy_balancerによる設定</h4>
<p>Apacheのmod_proxy_balancerでバックエンドから応答が返ってくるまでのタイムアウトを設定できる。<br />
これによりクライアントがタイムアウトする前に「502 ProxyError」を返すことができる。<br />
加えてErrorDocumentを適切に設定すればHTTP的には全くエラーが起きてないように振る舞うことも可能。</p>
<p>例えば以下のように設定すればバックエンドサーバーから4秒以内に応答が返ってこなかった場合にhttp://example.com/sorry.htmlへとリダイレクトされる。</p>
<pre><code>ProxyPass /example http://backend.example.com timeout=4
ErrorDocument 502 http://example.com/sorry.html</code></pre>
<p>このときクライアントへの応答は302のリダイレクトになり、http://example.com/sorry.htmlを表示した時点で200となる。</p>
<h4>注意すべきこと</h4>
<p>これでプラットフォームから課せられるペナルティの恐れはなくなったが、一方でエラー画面ばかり表示されるアプリに大してユーザーがどういう感想を抱き、どういう行動を取るかは明らか。<br />
またタイムアウトが起きているという事は把握しておかないとその状況を改善するための適切な対処がとれなくなるということも忘れてはならない。</p>
<p>ご利用は計画的に。</p>
<h4>ダメだった代替案</h4>
<p>もっと簡単にできないものかとちょっと調べたり試した。</p>
<h5>ApacheのTimeout</h5>
<p>このディレクティブが扱うのはクライアントとの通信のタイムアウトであって、内部処理がどれくらいかかったからタイムアウトさせるというものではなかった。<br />
Apache10年以上触ってるのに初めて知った衝撃の事実。</p>
<ul>
<li>参考:<a href="http://httpd.apache.org/docs/2.0/ja/mod/core.html#timeout">core &#8211; Apache HTTP サーバ</a></li>
</ul>
<h5>PHPのmax_execution_timeあるいはset_time_limit()</h5>
<p>これで設定できるのはスクリプト自体の実行時間の制限であって応答時間ではない、とのことだ。</p>
<p>つまりスクリプト自身が外部のリソースにアクセスして応答を待っている時間などは制限を受けない。<br />
例えばスクリプトからデータベースを叩いて応答を待っている時間などはスクリプトの実行時間ではない。</p>
<p>こういう事情により以下のコードはタイムアウトしない。</p>
<pre><code>< ?php
  set_time_limit(5);
  sleep(10); // 寝ている時間は実行時間に含まれない
  echo 'hoge';
?></code></pre>
<ul>
<li>参考:<a href="http://www.php.net/manual/ja/function.set-time-limit.php">PHP: set_time_limit &#8211; Manual</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/in-5sec-response.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPressのウィジェットの作り方</title>
		<link>http://brass.to/blog/how-to-make-wordpress-widget.html</link>
		<comments>http://brass.to/blog/how-to-make-wordpress-widget.html#comments</comments>
		<pubDate>Wed, 11 Aug 2010 12:25:59 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=575</guid>
		<description><![CDATA[今更だけどウィジェットが鬼便利。
WordPressよくできてるなあと感心する。
サイドバーに何か追加したいとき、標準のテキストウィジェットでテキストやHTMLのレベルですむものならさくっと追加できる。
簡単なPHPのコ [...]]]></description>
			<content:encoded><![CDATA[<p>今更だけどウィジェットが鬼便利。<br />
WordPressよくできてるなあと感心する。</p>
<p>サイドバーに何か追加したいとき、標準のテキストウィジェットでテキストやHTMLのレベルですむものならさくっと追加できる。<br />
簡単なPHPのコードを実行したい場合は<a href="http://wordpress.org/extend/plugins/php-code-widget/">PHP Code Widget</a>を使えばいける。</p>
<p>更にウィジェットを自作するともっといろいろなことができる。</p>
<p>そういうわけなので基本的な表示方法と、ウィジェットごとのオプションの設定の仕方について整理してみる。<br />
かなり簡単。</p>
<h4>まずは基本のHello World</h4>
<p>テキストウィジェットでいけるレベルであるが、最初の一歩はシンプルに。</p>
<pre><code>< ?php
/**
 * @package Hogehoge
 * @version 0.1
 */
/*
Plugin Name: Hoge Widget
Plugin URI: http://brass.to/
Description: Hoge Hoge Hoge
Author: akahige
Version: 0.1
Author URI: http://brass.to/
*/

class HogeWidget extends WP_Widget {
    function HogeWidget() {
      parent::WP_Widget(false, 'ほげうぃじぇっと');
    }

    function widget($args, $instance) {
      extract($args);

      echo $before_widget;
      echo 'Hello World!';
      echo $after_widget;
    }
}

add_action('widgets_init', create_function('', 'return register_widget("HogeWidget");'));</code></code></pre>
<p>これをWordPressのプラグインディレクトリにhoge_widget.phpとでも名前を付けて保存すれば動く。<br />
冒頭のコメントはプラグインとして認識させるためのコメント。</p>
<h5>WP_Widgetクラスを継承</h5>
<p>2.8以降はWP_Widgetを継承することでウィジェットを作成できる。<br />
それより前のバージョンでは作り方が違うが、今更過去を振り返る必要はないので割愛。</p>
<h5>コンストラクタ</h5>
<p>とりあえずウィジェットの管理画面に表示されるウィジェット名を設定。</p>
<h5>widgetメソッド</h5>
<p>widgetメソッドの中身がウィジェットに表示される内容になる。</p>
<p>$before_widgetやら$after_widgetやらはサイドバーごとに決まっているオプション。<br />
他のウィジェットとの和を乱さぬためにお約束として入れる。</p>
<p>echoが残念な感じだがサンプルなので気にしないことにする。</p>
<h5>ウィジェットの登録</h5>
<p>add_actionの行でウィジェット初期化時にウィジェットを登録して使用できるようにしている。<br />
この一行がないとウィジェットが使えるようにならない。</p>
<p>以上。<br />
表示はこれだけ。スゲー簡単。</p>
<h4>ウィジェットのオプションを設定できるようにする</h4>
<p>ウィジェットの管理画面でオプションを設定して、それをウィジェットの表示に使えるようにする。</p>
<p>オプションはウィジェットのインスタンスごとに保存されるので、同じ種類のウィジェットを複数配置してそれぞれ別のオプション内容に基づいた表示をさせることが可能。</p>
<pre><code>class HogeWidget extends WP_Widget {
    function HogeWidget() {
      parent::WP_Widget(false, $name = 'ほげうぃじぇっと');
    }

    function widget($args, $instance) {
      extract($args);
      $title = apply_filters('widget_title', $instance['title']);

      echo $before_widget;
      if ($title) echo $before_title . $title . $after_title;
      echo 'Hello ' . htmlspecialchars($instance['name']) . '!';
      echo $after_widget;
    }

    function update($new_instance, $old_instance) {
      $instance = $old_instance;
      $instance['title'] = strip_tags($new_instance['title']);
      $instance['name'] = strip_tags($new_instance['name']);
      return $instance;
    }

    function form($instance) {
      echo '&lt;div&gt;title:&lt;br /&gt;&lt;input name="' . $this-&gt;get_field_name('title') . '" type="text" value="' . $instance['title'] . '" /&gt;&lt;/div&gt;';
      echo '&lt;div&gt;name:&lt;br /&gt;&lt;input name="' . $this-&gt;get_field_name('name') . '" type="text" value="' . $instance['name'] . '" /&gt;&lt;/div&gt;';
    }
}</code></pre>
<h5>formメソッド</h5>
<p>formメソッドが管理画面のオプション設定フォームの内容。</p>
<p>get_field_nameでinputタグのnameを取得するのがミソ。<br />
$instanceには設定済みのオプションの値が入っている。</p>
<p>echoが残念なかんｊ（ｒｙ</p>
<h5>updateメソッド</h5>
<p>変更後の値（$new_instance）と変更前の値（$old_instance）が渡ってくるので、それらを使ってオプションとして保存する内容を返す。<br />
フォームでの入力内容を検証したり加工したりしたい場合にはここでいろいろと処理することができる。</p>
<p>変更後の値をそのまま使うのであれば</p>
<pre><code>return $new_instance</code></pre>
<p>の一行でもよい。<br />
というか親クラスのWP_Widgetでそういう内容になっているので、それでよければupdateメソッドの定義は略せる。</p>
<p>特にウィジェット用のテーブルなどを作らなくてもオプションを保存できるところが素敵。</p>
<h5>widgetメソッド</h5>
<p>設定したオプションの内容が$instanceに入っているのでそれを使うことができる。</p>
<p>新しく出てきている$before_titleやら$after_titleやらもサイドバーごとに決まっているオプション。</p>
<p>以上。<br />
これも簡単。</p>
<p>ほんとうにWordPressはよくできていると感心する。</p>
<h4>参考</h4>
<ul>
<li><a href="http://codex.wordpress.org/Widgets_API">Widgets API &laquo; WordPress Codex</a></li>
<li><a href="http://nulldesign.jp/blog/wordpress/109.html">WordPress カスタムウィジェットの作り方 &laquo;  nulldesign</a></li>
<li><a href="http://soft.fpso.jp/develop/wordpress/customize/entry_2333.html">WordPress 2.8でウィジェット作成(1) &#8211; Hello World | とりさんのソフト屋さん</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/how-to-make-wordpress-widget.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ウェブアプリの負荷テストについてのメモ</title>
		<link>http://brass.to/blog/stress-test-memo.html</link>
		<comments>http://brass.to/blog/stress-test-memo.html#comments</comments>
		<pubDate>Tue, 10 Aug 2010 00:43:48 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[インフラ]]></category>
		<category><![CDATA[パフォーマンスチューニング]]></category>
		<category><![CDATA[負荷テスト]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=562</guid>
		<description><![CDATA[負荷テストってどうやってやったらいいんだろう？
って長年思いつつ、適当にabとかで負荷かけてとりあえずDone、みたいなことでお茶を濁してきたわけだけど、最近のプロジェクトで腰を据えてやる機会があり一定の知見を得たのでメ [...]]]></description>
			<content:encoded><![CDATA[<p>負荷テストってどうやってやったらいいんだろう？<br />
って長年思いつつ、適当にabとかで負荷かけてとりあえずDone、みたいなことでお茶を濁してきたわけだけど、最近のプロジェクトで腰を据えてやる機会があり一定の知見を得たのでメモっておく。</p>
<p>手順と心がけるべきいくつかの事柄について。</p>
<h4>手順</h4>
<ul>
<li>かける負荷の規模を決める</li>
<li>シナリオを作る</li>
<li>ツールを準備する</li>
<li>負荷テスト対象のサーバーを準備する</li>
<li>負荷をかける側のマシンを準備する</li>
<li>データを準備する</li>
<li>負荷テストを走らせる</li>
<li>計測結果を記録する</li>
</ul>
<h5>かける負荷の規模を決める</h5>
<p>並列度とシナリオのループ回数くらいを決めておく。<br />
1000並列で5000ループ、みたいな。</p>
<p>パフォーマンスの目標値があればそれをそのまま使うか、目安にできる。</p>
<h5>シナリオを作る</h5>
<p>ユーザーの実際の動きを想定した画面遷移のシナリオを作る。<br />
これはURLのリストでよい。（リダイレクトなどは考慮すること）</p>
<p>負荷テストをより意味あるものにするためには、実際のユーザーの動きをより忠実に再現したものであることが望ましい。<br />
サービス開始後ならばログから精度の高いシナリオが作成できる。<br />
サービス開始前でもクローズドベータなどで実際のユーザーにさわってもらう機会があれば、そのログからよいシナリオが作れる。</p>
<p>また思わぬところに潜んでいるボトルネックを洗い出すためにシナリオはすべての処理を網羅するようにする。</p>
<h5>ツールを準備する</h5>
<ul>
<li>多数のユーザーが</li>
<li>同時にアクセスして</li>
<li>一連のシナリオ（画面遷移）をたどる</li>
</ul>
<p>という動作をシミュレートできるツールならばなんでもよい。<br />
これらはアプリの負荷テストには必須。</p>
<p>abは指定できるURLがひとつだけなのでちょっと力不足ということになる。<br />
単一ページのチューニングのお供にはお手軽でよいだろうけど。</p>
<p>このあたりは得意な言語で使い捨てのスクリプトを組んでも良いと思う。<br />
また探せばいいツールがいくつかあるようだ。</p>
<ul>
<li>参考: <a href="http://www.itmedia.co.jp/enterprise/articles/0901/15/news023.html">Programing Bible：Webの負荷テストに使えるフリーソフトウェア (1/2) &#8211; ITmedia エンタープライズ</a></li>
</ul>
<p>ツール選びの基準としては上記の必須項目の他に以下のようなものがあげられる。</p>
<ul>
<li>動作が軽い</li>
<li>設定が簡単</li>
<li>レポーティング機能がすぐれている</li>
</ul>
<p>動作が軽くないと負荷をかける側がボトルネックになって十分に負荷をかけられない場合がある。<br />
そういう意味でJMeterは重いのでよろしくないと思う。</p>
<p>負荷テストについて考える際にいろいろと参考にした『<a href="http://www.amazon.co.jp/gp/product/4873113997?ie=UTF8&#038;tag=outdoorcook-22&#038;linkCode=as2&#038;camp=247&#038;creative=7399&#038;creativeASIN=4873113997">キャパシティプランニング</a>』ではhttperfとかSiegeをおすすめしている。</p>
<h5>テスト対象のサーバーを準備する</h5>
<p>本番に近い構成のサーバーを準備する。<br />
そういう意味ではサービスのローンチ直前などは本番環境でのテストがやりやすくていい。</p>
<p>負荷をかける側にもリソースが必要になるので、本番環境の構成の半分とか四分の一とかの構成でテストする場合もある。</p>
<p>ローンチ後の負荷テストに関しては理想的には本番環境と同等のテスト環境があればよいが、そんな恵まれた環境は滅多にないと思うのでいったいどうしたらいいのだろうか。<br />
このあたり答えが出ていない。<br />
環境構築やデプロイの自動化が十分にできていればクラウドを使うという選択もあるのだろうか。</p>
<h5>負荷をかける側のマシンを準備する</h5>
<p>負荷をかける側のマシンも十分に強くないと、負荷をかける側の限界が先に来てしまって負荷をかけきれないので、こちらもちゃんと準備する。<br />
できれば複数台がよい。</p>
<p>ちょっと前までは負荷テスト用にマシンを複数台確保するというのはなかなか現実的ではなかったけれど、最近はEC2などのクラウドがあるので容易に必要なだけ安価に調達できるようになった。<br />
こういうところはまさにクラウドの使いどころ。</p>
<h5>データを準備する</h5>
<p>サービス開始当初は問題がなくても、データがたまってきて問題が出てくるケースというのは多い。<br />
なので大量の実データを準備することも必要。</p>
<p>データ投入はSQLで行うのが一番速いが、一方で実際にアプリを運用した場合に比べるとデータの抜けが発生する可能性も高い。<br />
なのでSQLによるバルクインサートなどより時間はかかるが実際にアプリの動作によってデータを作るのが一番確実なデータを準備できると思う。</p>
<p>具体的には負荷テストツールでデータの生成をともなうシナリオを作って走らせる。<br />
一度生成したデータはバックアップしておけば、次回データを準備するのは短時間でできるようになる。</p>
<h5>負荷テストを走らせる</h5>
<p>いろいろと準備ができたので負荷テストを実行する。<br />
最初は少ない負荷をかけてアプリが正しく動いているかどうかを確認する。</p>
<p>これだけ負荷をかけているのにスゴいパフォーマンスだ！<br />
とか思ったら実はほとんどのページがエラーになっていて処理をきちんと実行していなかったなんてこともあり得るので。</p>
<p>一連のシナリオが正しく動いていることが確認できたら本腰を入れて負荷をかける。</p>
<p>負荷をかける側のリソース状況を見て、そちらがいっぱいいっぱいになってないことを確認する。<br />
負荷をかける側がいっぱいいっぱいになっていたら十分に負荷をかけ切れてない可能性があるので、マシンの追加などを検討する。</p>
<h5>計測結果を記録する</h5>
<p>実行条件とともにしっかり記録しておく。<br />
この結果がパフォーマンスチューニングやキャパシティプランニングの指標になる。</p>
<ul>
<li>負荷テストツールのレポート結果</li>
<li>負荷をかけている間のサーバーのモニタリング結果</li>
<li>httpdのログ</li>
<li>スロークエリログ</li>
</ul>
<p>クライアントから見たパフォーマンスとサーバー側のリソースの変化の両面から。<br />
モニタリングに関してはMRTG、Munin、ZABBIXなどのツールで負荷がかかっている間のグラフが見られるようにしておくとよい。</p>
<p>httpdのログにはレスポンスタイムを含めるようにしておく。（ApacheならばLogFormatに%Dを加える）<br />
そうすれば後で重いページを探し出すことができる。</p>
<p>スロークエリは0.1秒以上かかったらNGとか条件を厳しめにしておくと問題を効果的にあぶり出せる。</p>
<h4>心がけるべきいくつかの事柄</h4>
<h5>負荷テストは負荷をかける側も痛みを伴う</h5>
<p>負荷をかける側のマシンリソースが十分でないと負荷をかけきれないことのほか、ウェブアプリの負荷テストはネットワーク帯域を圧迫する。<br />
ネットワーク帯域は意外と盲点なので注意。</p>
<h5>パフォーマンスチューニングと負荷テストは別</h5>
<p>テスト駆動開発で実装の帽子とリファクタリングの帽子を交互にかぶり直すように、チューニングの帽子と負荷テストの帽子も交互にかぶり直すようにする。<br />
つまりふたつを一緒くたにして同時にやらないように。</p>
<p>これらを同時にやり始めると、ちょっとパラメータを変更しては負荷テストを繰り返すといったスパイラルに陥ってしまいがち。<br />
このスパイラルはとても楽しいが、かかる時間の割に得られるものはそれほど多くない。</p>
<p>負荷テストの第一の目的はパフォーマンスの計測であって、パフォーマンスの向上はまた別の話。<br />
そのあたりの線引きを意識しておかないと無駄に負荷テストを繰り返して時間を浪費してしまいかねない。</p>
<h5>スロークエリはダメ、絶対</h5>
<p>ごくまれにしかアクセスされないページにひとつスロークエリが潜んでいるだけで一気にパフォーマンスが半減したりする。（実のところ本当に50%減とかする）<br />
高負荷時にはひとつの小さな傷が致命傷になりかねないという話。</p>
<p>負荷テストを要するようなシステムではスロークエリは致命的なバグと同列と言っていい。</p>
<p>また、そうした重箱の隅に潜んでいるスロークエリをあぶり出すためにもシナリオはすべての処理を網羅している必要がある。</p>
<h4>追記</h4>
<p>- 手順の項にかける負荷の規模についてなど追記。</p>
<p>ほか何か思いついたら適宜追記していくかも。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/stress-test-memo.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPressのプラグイン用テーブルの追加</title>
		<link>http://brass.to/blog/wordpress-create-table-for-plugin.html</link>
		<comments>http://brass.to/blog/wordpress-create-table-for-plugin.html#comments</comments>
		<pubDate>Mon, 09 Aug 2010 06:55:40 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=556</guid>
		<description><![CDATA[自作プラグインでテーブルを作成する必要があったのでメモ。
以下の二点がわかれば如何様にも作れる。

プラグインを有効化したときに処理を実行する方法
テーブルを作成する方法

プラグイン有効化時のフック処理
有効化時に実行 [...]]]></description>
			<content:encoded><![CDATA[<p>自作プラグインでテーブルを作成する必要があったのでメモ。<br />
以下の二点がわかれば如何様にも作れる。</p>
<ul>
<li>プラグインを有効化したときに処理を実行する方法</li>
<li>テーブルを作成する方法</li>
</ul>
<h4>プラグイン有効化時のフック処理</h4>
<p>有効化時に実行する処理を関数として定義してregister_activation_hookで登録する。</p>
<pre><code>function hoge_plugin_activate() {
  hoge_setup_table('hoges');
}
register_activation_hook(__FILE__, 'hoge_plugin_activate');</code></pre>
<p>register_activation_hookの第一引数は関数が定義されているファイル。<br />
同じファイルなので「__FILE__」でよい。別のファイルに切り出すならそのファイル名を指定する。</p>
<p>第二引数がフック処理を定義した関数名。<br />
WordPress本体や他のプラグインが提供する関数とかぶらないような名前を付ける。</p>
<h4>テーブル作成処理</h4>
<p>テーブルの有無を確認してなければ作成するというのが一般的な処理。<br />
別のテーブルを作るときでも使えるようにhoge_setup_table関数として切り出した。</p>
<pre><code>function hoge_setup_table($table_name) {
  global $wpdb;
  if ($wpdb->get_var("show tables like'" . table_name_with_prefix($table_name) . "'") != table_name_with_prefix($table_name)) {
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    $sql_create_func = "sql_create_$table_name";
    $sql = $sql_create_func();
	add_option("hoges_version", '1.0');
    dbDelta($sql);
  }
}</code></pre>
<p>$sql_create_funcはSQLを得るためのテーブル名に応じた関数。テーブル名から機械的に関数名を作る。<br />
add_optionはプラグインを更新した際にテーブル構造が変わる可能性があるのでプラグインのバージョン番号を記録しておくのだそうだ。</p>
<p>プレフィックス付きのテーブル名を使う機会は作成時以外にもいろいろあるので、関数として定義。</p>
<pre><code>function table_name_with_prefix($table_name) {
  global $wpdb;
  return $wpdb->prefix . $table_name;
}</code></pre>
<p>SQLを返す関数は以下のように定義する。テーブル名がhogesなのでsql_create_hoges。</p>
<pre><code>function sql_create_hoges() {
  return "CREATE TABLE " . table_name_with_prefix('hoges') . "(
    id int not null auto_increment,
    name varchar(255) not null,
    primary key(id)
  );";
}</code></pre>
<p>dbDeltaの仕様的に「CREATE TABLE」は大文字でなくてはならない。なんかイマイチだけど仕方ない。</p>
<h4>その他メモ</h4>
<h5>テーブル作成のデバッグ</h5>
<p>SQLが間違っていてテーブルが作成されないことがあるが、エラーがあっても出力されないので、add_option又はupdate_optionによってSQLを記録してデバッグした。<br />
なんかもっと他に良い方法があるかもしれないが・・・</p>
<h5>削除時にテーブルを削除するか？</h5>
<p>再び有効にすることも考えられるので、普通は削除しなくてもよいだろう。<br />
削除したければregister_deactivation_hookを利用すればよい。</p>
<h5>$wpdbやdbDeltaを使わなくてもいいのでは</h5>
<p>まあ郷に入れば郷に従えということで。</p>
<h4>参考</h4>
<ul>
<li><a href="http://codex.wordpress.org/Creating_Tables_with_Plugins">Creating Tables with Plugins &laquo; WordPress Codex</a></li>
<li><a href="http://codex.wordpress.org/Function_Reference/register_activation_hook">Function Reference/register activation hook &laquo; WordPress Codex</a></li>
<li><a href="http://codex.wordpress.org/Function_Reference/wpdb_Class">Function Reference/wpdb Class &laquo; WordPress Codex</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/wordpress-create-table-for-plugin.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dropbox+Gitでフリーのプライベートリポジトリ</title>
		<link>http://brass.to/blog/dropboxgit.html</link>
		<comments>http://brass.to/blog/dropboxgit.html#comments</comments>
		<pubDate>Thu, 05 Aug 2010 01:44:35 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[作業環境]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=553</guid>
		<description><![CDATA[最近開発マシンとしてMacとUbuntuを併用しているのでDropboxが手放せない。
単なるファイル共有だけではなく、DropboxにGitのマスターリポジトリを入れておくとプライベートリポジトリとして使えてますます便 [...]]]></description>
			<content:encoded><![CDATA[<p>最近開発マシンとしてMacとUbuntuを併用しているのでDropboxが手放せない。<br />
単なるファイル共有だけではなく、DropboxにGitのマスターリポジトリを入れておくとプライベートリポジトリとして使えてますます便利に。</p>
<ul>
<li>参考:<a href="http://naoki.sato.name/lab/archives/38">gitとDropboxでお手軽・無料のSource Hostingを実現する &laquo;  lab.naoki.sato.name</a></li>
</ul>
<p>フリーのプライベートリポジトリが持てるサービスもあるけれど、新しくそういったサービスのアカウントを増やさなくていいので気軽に使える。</p>
<p>ただし複数人で共有するようなリポジトリの運用は難しい。<br />
Dropboxには他ユーザーとのファイル共有機能があるのでいけるかな、と思ったがよく考えるとファイル更新の衝突（リビジョンの衝突ではなく）が起こる可能性があるのでその当たりに気を遣う必要がでてくる。</p>
<ul>
<li>参考:<a href="http://d.hatena.ne.jp/magnitude6/20100118/p1">【メモ】衝突検知 &#8211; ヒマは見つけるモノじゃない、つくるモノだ</a></li>
</ul>
<p>がんばればいけそうだけど、素直に他のサービスを使った方がよさげ。<br />
フリーのサービスは「フリー プライベートリポジトリ」でぐぐればいろいろ出てくる。<br />
またパブリックなリポジトリでよけばGoogle CodeやGitHubでよい。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/dropboxgit.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>iPadアプリ出しました『温泉探索地図』</title>
		<link>http://brass.to/blog/ipad-app-release.html</link>
		<comments>http://brass.to/blog/ipad-app-release.html#comments</comments>
		<pubDate>Wed, 04 Aug 2010 06:04:18 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iOS開発]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=548</guid>
		<description><![CDATA[
iPhoneアプリとして出していた『温泉探索地図』をiPad対応させました。
えー、酒代にするので買ってください。よろしくお願いします。
iPad/iPhoneのユニバーサルアプリになっているのでひとつのアプリで両方で [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://brass.to/blog/wp-content/uploads/2010/08/IMG_0004.PNG.jpg"><img src="http://brass.to/blog/wp-content/uploads/2010/08/IMG_0004.PNG.jpg" alt="" title="温泉探索地図" width="512" height="384" class="alignleft size-full wp-image-549" /></a></p>
<p>iPhoneアプリとして出していた『温泉探索地図』をiPad対応させました。</p>
<p>えー、酒代にするので買ってください。よろしくお願いします。<br />
iPad/iPhoneのユニバーサルアプリになっているのでひとつのアプリで両方で使えてお得です。</p>
<p>両対応する作業はiPad独自のSplitViewControllerやPopoverControllerの勝手がわかればそれほど大変でもなかった。<br />
その他の処理はiPadの場合とiPhoneの場合で条件分岐するコードをちょっと埋めたくらいで問題なく。</p>
<p>しかし今回は審査にけっこう時間がかかった。<br />
7/24に提出して、In Reviewになったのが7/31、Ready for Saleになったのが8/3。<br />
10日以上かかっている。<br />
スケジュールに合わせて出そうとするなら、リジェクトされる可能性も考えるとずいぶん時間を見ておかないと心配だ。<br />
自分の場合はいつ出てもでなくても大して問題はないが、何かのキャンペーンに合わせてアプリを出したりとかしようとすると大変だろうなあ。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/ipad-app-release.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android開発環境の構築</title>
		<link>http://brass.to/blog/start-android-development.html</link>
		<comments>http://brass.to/blog/start-android-development.html#comments</comments>
		<pubDate>Thu, 29 Jul 2010 00:58:01 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Android開発]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=539</guid>
		<description><![CDATA[備忘メモ。
IDEを使う気は今のところないのでシェルとVimでがんばる方針。
開発マシンはUbuntu 9.10 or Mac(Snow Leoperd)。
手順は以下。
* Java環境の整備
* Android SD [...]]]></description>
			<content:encoded><![CDATA[<p>備忘メモ。<br />
IDEを使う気は今のところないのでシェルとVimでがんばる方針。<br />
開発マシンはUbuntu 9.10 or Mac(Snow Leoperd)。</p>
<p>手順は以下。</p>
<p>* Java環境の整備<br />
* Android SDKをインストール<br />
* AVD（仮想デバイス）を作る<br />
* プロジェクトを作る<br />
* Hello worldしてみる</p>
<h4>Java環境の整備</h4>
<p>MacはSnow Leoperdに最初から入ってるやつを使う。<br />
Ubuntuは以下のコマンドでインストール。antも入れておく。</p>
<pre><code>$ sudo apt-get install sun-java6-jdk ant</code></pre>
<p>64bit版の場合はia32-libsというパッケージもいるらしい。</p>
<h4>Android SDKをインストール</h4>
<p>以下のページからそれぞれのプラットフォームに対応したものを落とす。</p>
<ul>
<li><a href="http://developer.android.com/sdk/index.html">Android SDK | Android Developers</a></li>
</ul>
<p>落としたものを展開。<br />
展開されたディレクトリ名には「-mac_86」とか「-linux_86」とか書いてあるけども、パス設定を共通にしたいのでその部分を取り除いて/opt/local以下に置く。</p>
<p>その上でandroid-sdk/toolsにパスを通す。激しく手動。</p>
<pre><code>$ export PATH=/opt/local/android-sdk/tools:$PATH</code></pre>
<p>.zshrcにも書いておく。</p>
<p>ここまでやった時点で</p>
<pre><code>$ android</code></pre>
<p>とコマンドを実行すると「Android SDK and ADV Manager」なるGUIが立ち上がる。<br />
左メニューからInstalled Packageを選択して「Update all」するといろいろと落ちてくる。</p>
<p>これで一応SDKのインストールは完了。</p>
<h4>AVD（仮想デバイス）を作る</h4>
<p>仮想デバイスはいわゆるシミュレータ。<br />
実機がなくてもAndroidアプリの動作確認ができる。</p>
<p>AVDの作成は上記のGUIでもできるがコマンドラインでも簡単にできる。</p>
<pre><code>$ android create avd -n A16 -t 4</code></pre>
<p>-nは &#8211;name の略。<br />
適当に任意の仮想デバイス名をつける。</p>
<p>-tは &#8211;target の略。<br />
仮想デバイスのOSバージョンごとに決まっているIDを指定するのだが、これは連番で振られているようだ。<br />
どのIDがどのバージョンに対応しているかはGUIでの作成を見たら表示順でなんとなくわかる。たぶんどこかにまとまっているのだろうけど。</p>
<p>作成した仮想デバイスは以下のコマンドで起動できる。</p>
<pre><code>$ emulator -avd A16</code></pre>
<p>起動にはちょっと時間がかかる。</p>
<p>まあここまではIDEに依存しているわけではないので、GUIでもいいでしょう。</p>
<h4>プロジェクトを作る</h4>
<p>EclipseなどのIDEを使わない場合はコマンドラインで。従ってここからはコマンドライン必須。</p>
<pre><code>$ android create project -n HelloWorld -t 4 -p /path/to/project --a HelloWorld -k com.example.Hello</code></pre>
<p>これでできた。<br />
オプションの詳細は<a href="http://developer.android.com/guide/developing/other-ide.html">Developing In Other IDEs | Android Developers</a>参照。</p>
<h4>Hello worldしてみる</h4>
<p>作ったプロジェクトのディレクトリに移動してコードを書く。<br />
コードは以下のチュートリアル通りに。</p>
<p><a href="http://developer.android.com/resources/tutorials/hello-world.html">Hello, World | Android Developers</a></p>
<p>仮想デバイスで動かすときだけ以下のコマンド。<br />
このantタスクはデバイスにアプリをインストールするためのadbというコマンドをラップしてくれているっぽい。</p>
<pre><code>$ ant install</code></pre>
<p>これで仮想デバイスにインストールされたアプリを起動すると、感動のHelloWorldが！</p>
<p>なおデバイスを起動しておかないとインストールできないので注意。</p>
<p>これで環境構築はおしまい。<br />
あとはSDKのドキュメントなど読んでアプリ開発がんばる。</p>
<h4>参考</h4>
<ul>
<li><a href="http://developer.android.com/sdk/installing.html">Installing the SDK | Android Developers</a></li>
<li><a href="http://developer.android.com/guide/developing/other-ide.html">Developing In Other IDEs | Android Developers</a></li>
<li><a href="http://blogs.sun.com/katakai/entry/configure_jdk_on_ubuntu_9">Ubuntu 9.04 に JDK をインストールする &#8211; Masaki Katakai&#8217;s Weblog</a></li>
<li><a href="http://ronor.blog81.fc2.com/blog-entry-24.html"> Shellとvim上で開発する方法(Android) &#8211; ARGENTO CUORE</a></li>
</ul>
<p>ほか公式のDev Guideにいろいろとまとまっている。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/start-android-development.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>最近の個人的なiPhoneやらXperiaやら周辺の通信環境</title>
		<link>http://brass.to/blog/mobile-network-201007.html</link>
		<comments>http://brass.to/blog/mobile-network-201007.html#comments</comments>
		<pubDate>Wed, 28 Jul 2010 14:55:18 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=529</guid>
		<description><![CDATA[今年になってからモバイルの通信環境についていろいろ検討していた。

iPhone4に乗り換える！ &#8211; ひげろぐ 
来るべきiPadに向けて回線について考える &#8211; ひげろぐ 

現状はこうなった。
 [...]]]></description>
			<content:encoded><![CDATA[<p>今年になってからモバイルの通信環境についていろいろ検討していた。</p>
<ul>
<li><a href="http://brass.to/blog/goodbye-au-hello-iphone4.html">iPhone4に乗り換える！ &#8211; ひげろぐ </a></li>
<li><a href="http://brass.to/blog/ipad-networking.html">来るべきiPadに向けて回線について考える &#8211; ひげろぐ </a></li>
</ul>
<p>現状はこうなった。</p>
<ul>
<li>iPhone 4 パケットし放題フラット</li>
<li>Pocket Wifi ギガデータプラン</li>
<li>Xperia auから乗り換えてネット利用を一切やめた</li>
</ul>
<p>Pocket Wifi分増えたけども、電話用の端末でのネット利用をやめたことで通信エンゲル係数はほぼ変わらず。</p>
<h5>iPhoneとPocket Wifi</h5>
<p>iPhoneに関してはiPhone 4予約時の縛りで使っても使わなくてもパケット通信料が4,410円。<br />
そんなわけでPocket Wifiとの併用でiPhoneの通信費を抑えるという目論見は露と消えた。</p>
<p>実はiPhoneの通信をPocket Wifi経由にすると言うのは一時期やってみていたのだが、実際やってみるとiPhoneで通信を始める前にPocket Wifiの電源を入れなくてはならないというのは致命的に不便だった。<br />
iPhoneの使い勝手が激しくスポイルされてしまい、正直その手間をなくすのに月3,000円くらいだったら払ってやるよ、といったレベル。<br />
なのでiPhone 4予約時にパケットし放題フラットの契約縛りの文言を見ても迷わず予約した。</p>
<p>Pocket Wifiは宙に浮いてしまった形とも言えるが、外出時にiPadやノートPCを持って行く場合に積極的に使っている。<br />
プランは今後の様子を見て調整していくつもり。</p>
<h5>電話回線と実験機としてのXperia</h5>
<p>Xperiaは電話用のdocomo回線のためと、Android開発にも最近興味があるので、実機確保としてゲット。<br />
山間部でのバイクの故障や事故などの可能性を考えるとSoftbank一本化はちょっと厳しい。<br />
OSが2.1にアップグレードされるというウワサをあてにして買ったので、もしアップグレードされなかったらちょっと悲しい。<br />
ネットワークはWifiのみで利用している。</p>
<p>ガラケーでなくなってしまったため、キャリアからの通信のみに制限しているモバイルサイトは見られなくなってしまったが、出先での情報検索などはiPhoneにすでにシフトしていたので個人的な利用に不便はない。<br />
仕事的にも簡単な表示確認だったら実機はなくてもできるし、逆に本格的に実機確認しようと思ったら自分が持っている一機種だけじゃどうせ焼け石に水なので問題はない。</p>
<p>・・・とか思ってたら携帯ソーシャルアプリがらみの仕事なんかではちょっと不便だったのがやや誤算ではあった。</p>
<p>にしても久々に店頭で携帯の契約とかしたけれど、料金プランとか口頭で説明されても理解不能。複雑すぎです。<br />
いらんオプションもいろいろと勧めてくるし、通信費安くした分をそういうところでがんばって回収しようとしているのかな？とか思った。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/mobile-network-201007.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS開発で遭遇した謎のエラーたち</title>
		<link>http://brass.to/blog/ios-dev-errors.html</link>
		<comments>http://brass.to/blog/ios-dev-errors.html#comments</comments>
		<pubDate>Wed, 21 Jul 2010 18:50:04 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iOS開発]]></category>
		<category><![CDATA[iPhone開発]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=525</guid>
		<description><![CDATA[メモをあげておく。
基本をちゃんと理解してれば謎ではないんでしょうが。
unrecognized selector sent to instance hogehogeっつってるけど

定義されてないメソッド、またはint [...]]]></description>
			<content:encoded><![CDATA[<p>メモをあげておく。<br />
基本をちゃんと理解してれば謎ではないんでしょうが。</p>
<h5>unrecognized selector sent to instance hogehogeっつってるけど</h5>
<ul>
<li>定義されてないメソッド、またはinterfaceで公開されてないメソッドを使った</li>
<li>対象のオブジェクトを使った覚えがない場合はポインタが意図してないアドレスを見てる</li>
</ul>
<p>後者はメモリ周りで以下のように適当にやってると起こる。</p>
<ul>
<li>まだ使われているオブジェクトを解放してるかもしれない releaseしすぎ</li>
<li>またはautorelease対象を解放してるかもしれない releaseしすぎ</li>
</ul>
<p>プロパティへの代入はセッターでretainされてるかされてないかちゃんと意識すること。</p>
<h5>error: expected specifier-qualifier-list before &#8216;HogeController&#8217;</h5>
<ul>
<li>クラスが見つからないようだ</li>
<li>フレームワークとか他のクラスのヘッダファイルとかインポートし忘れてないか確認</li>
<li>忘れてないのにアレだったら@classを使うとなんとかなるかもしれない</li>
</ul>
<p>@classが必要なケースはいろいろとインポートしていて順序の前後関係がごちゃごちゃしている時？<br />
よくわからず。</p>
<h5>ユニバーサルプロジェクトがiPhoneで動いてくれません</h5>
<ul>
<li>「データフォーマッタが一時的に使用できなくなっています。」って言われてもなんのことだか</li>
<li>UIKitをWeak LinkingにするとかNSClassFromStringを使うとかして解決</li>
<li>参考:http://useyourloaf.com/blog/2010/6/21/symbol-not-found-errors-in-universal-apps.html</li>
<li>参考:http://d.hatena.ne.jp/KishikawaKatsumi/20100625/1277476249</li>
</ul>
<h5>何も言わずに止まりやがる</h5>
<ul>
<li>コントローラのViewを作り忘れてるのにそれにaddSubviewとかいけませんよね</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/ios-dev-errors.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RubyのoauthでSignature検証</title>
		<link>http://brass.to/blog/ruby-oauth-signature-verify.html</link>
		<comments>http://brass.to/blog/ruby-oauth-signature-verify.html#comments</comments>
		<pubDate>Wed, 07 Jul 2010 16:06:33 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=516</guid>
		<description><![CDATA[なんかサンプルコードが見つからなかったので書いておく。
OAuth::Signitureというクラスが利用できる。
require 'oauth'

def verify(request)
  consumer = OA [...]]]></description>
			<content:encoded><![CDATA[<p>なんかサンプルコードが見つからなかったので書いておく。</p>
<p>OAuth::Signitureというクラスが利用できる。</p>
<pre><code>require 'oauth'

def verify(request)
  consumer = OAuth::Consumer.new(
    'SOME CONSUMER KEY', 'SOME CONSUMER SECRET',
    :site => 'http://api.example.com'
  )

  headers = oauth_headers(request)
  signature = OAuth::Signature.build(request) do
    [headers['oauth_token_secret'], consumer.secret]
  end

  signature.verify
end

def oauth_headers
  headers = {}
  request.env['HTTP_AUTHORIZATION'].split(',').each{|item| k, v = item.split('='); headers[k.strip] = v.gsub(/"/, '')}
  headers
end</code></pre>
<p>OAuth::Signature.buildの部分は</p>
<pre><code>signature = OAuth::Signature.build(request) </code></pre>
<p>だったり</p>
<pre><code>signature = OAuth::Signature.build(request) do
  [nil, consumer.secret]
end</code></pre>
<p>でよかったりすることもあると思いますよ。</p>
<h4>コード解説</h4>
<h5>requestって何者</h5>
<p>requestはRailsのコントローラ内で使えるものをそのまま渡せる。</p>
<p>Sinatraなどの場合もrequestという名前で定義されているものを基本そのまま渡せるが、以下のrequireが必要。</p>
<pre><code>require 'oauth/request_proxy/rack_request'</code></pre>
<p>requestは内部的にOAuth::RequestProxy::Baseのサブクラスに適宜変換される模様。</p>
<h5>oauth_headersメソッド</h5>
<p>oauth_headersメソッドはoauth_token_secretが取れなかったので作ったメソッド。</p>
<p>他のoauth_tokenなどの値はOAuth::RequestProxyを使うと取得できる。</p>
<pre><code>request_proxy = OAuth::RequestProxy.proxy(request)
request_proxy.oauth_token
request_proxy.signature</code></pre>
<p>などで取れるんだけど、なんでかoauth_token_secretは取れず。</p>
<h4>自前でSignatureを求める</h4>
<p>ついでにSignature Base Stringから自分で求めてみる方法も。</p>
<p>Signatureがどうしても一致しない場合の原因究明をする場合などに、自前でやる方法は把握しておくと役に立つ。<br />
# というかRubyのoauthのドキュメントが整備不足なのでこのあたり自前実装している人が多いような気がする。</p>
<pre><code>require 'openssl'
require 'oauth'

def my_signature(consumer, request)
  headers = oauth_headers(request)
  signature = OAuth::Signature.build(request) do
    [headers['oauth_token_secret'], consumer.secret]
  end

  digest = OpenSSL::Digest::Digest.new("sha1")
  secret = "#{escape(consumer.secret)}&#{escape(headers['oauth_token_secret'])}"
  signature_string = Base64.encode64(OpenSSL::HMAC.digest(digest, secret, signature.signature_base_string)).chomp.gsub(/\n/, "")
end

def escape(value)
  URI.escape(value.to_s, /[^a-zA-Z0-9\-\.\_\~]/) # Unreserved characters -- must not be encoded
end 

# oauth_headersは略</code></pre>
<p>上記コードの自前Signatureを求めるあたりは<a href='http://github.com/maccman/roauth'>roauth</a>から拝借した。</p>
<p>Signature Base String求めるとこは手抜きして既存のOAuth::Signatureを使ったもので。<br />
まあSignature Base Stringがおかしい場合は目視でわかるので、自分でSignature計算する前にまずはそこを見てみればいいのかも。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/ruby-oauth-signature-verify.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS開発 2010年6月終わり頃の記録</title>
		<link>http://brass.to/blog/ios-dev-tips-201006.html</link>
		<comments>http://brass.to/blog/ios-dev-tips-201006.html#comments</comments>
		<pubDate>Mon, 28 Jun 2010 16:17:48 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iOS開発]]></category>
		<category><![CDATA[iPhone開発]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=506</guid>
		<description><![CDATA[土日にいろいろやったので記憶の定着をかねてメモっておきますよ。
画像を回転させる

SDK 4.0からは既存のUIImageからCGImageを取得して、そこから回転を指定した新しいUIImageが作れる
でも今3.2な [...]]]></description>
			<content:encoded><![CDATA[<p>土日にいろいろやったので記憶の定着をかねてメモっておきますよ。</p>
<h5>画像を回転させる</h5>
<ul>
<li>SDK 4.0からは既存のUIImageからCGImageを取得して、そこから回転を指定した新しいUIImageが作れる</li>
<li>でも今3.2なのでめんどくさいから回転した画像を別途作った</li>
</ul>
<h5>ナビゲーションバーに複数ボタン </h5>
<ul>
<li>普通にやると右と左に一個ずつ（合計二個）しか作れない</li>
<li>ツールバーにまとめて、そのツールバーをもとにしたUIBarButtonItemを作るかんじ</li>
<li>参考:<a href="http://osmorphis.blogspot.com/2009/05/multiple-buttons-on-navigation-bar.html">Osmorphis: Multiple Buttons on a Navigation Bar</a></li>
</ul>
<h5>ボタンの見た目を画像に</h5>
<ul>
<li>UIButtonを作る。その背景画像をボタンの外観にしたい画像にする</li>
<li>UIBarButtonItem initWithCustomViewでナビゲーションアイテムを作成</li>
<li>参考:<a href="http://akisute.com/2010/04/uibarbuttonitem.html">A-Liaison BLOG: UIBarButtonItem の見た目を画像にしたいときのテクニック</a></li>
</ul>
<h5>Safariで開く</h5>
<ul>
<li>openURLしたらSafariで開く。超簡単。</li>
</ul>
<h5>標準のマップアプリで開く </h5>
<ul>
<li>Google MapのURLを指定してopenURLした時にマップアプリがインストールされていればマップアプリが開く</li>
<li>シミュレータにはマップアプリが入ってないのでSafariでGoogle Mapが開く</li>
<li>開いた後にマーカーをたてるにはq=で場所の名前も指定する必要あり ちゃんとURLエンコードする</li>
<li>参考:<a href="http://iphonedevelopertips.com/cocoa/launching-other-apps-within-an-iphone-application.html">Launching Other Apps within an iPhone Application</a></li>
<li>参考:「Custom URL Schemes」でぐぐれ</li>
</ul>
<h5>テーブルのセルの追加と削除時にアニメーション</h5>
<ul>
<li>処理の前後でセル数を返すメソッドの返値とセル数が一致していることが肝</li>
<li>参考:<a href="http://konton.ninpou.jp/program/cocoa/userinterface/UITableView/UITableView2.html">UITableViewの使い方その2:編集モード編</a></li>
</ul>
<h5>iPadでボタンからActionSheetが出ているように表示する方法</h5>
<ul>
<li>showFromBarButtonItemとかいうメソッドがあるのでそれを使う</li>
</ul>
<h5>アクティビティインジケータの表示</h5>
<ul>
<li>UIActivityIndicatorViewを使う</li>
<li>NavigationItemとして直接使えないのでaddSubviewで。frameでうまいこと位置は調整。</li>
<li>別スレッドで実行しないとだめとかハマりどころがあるそうな</li>
<li>参考:<a href="http://blog.mudaimemo.com/2010/05/iphoneuiactivityindicatorview.html">無題メモランダム: [iPhone]UIActivityIndicatorViewでハマった件</a></li>
<li>ステータスバーに表示するだけの簡易なものでよければ以下</li>
<li>参考:<a href="http://d.hatena.ne.jp/shunsuk/20090701/1246448058">iPhoneのステータスバーにインジケーターを表示する（iPhone SDKの話） &#8211; このブログは証明できない。</a></li>
</ul>
<p>開発の近況としてはだいぶ慣れてきて分からないことにも推測が働くので結構楽になってきた。<br />
あと基本的なことは本家のリファレンスを見ることでだいたい解決できるようになってきたけど、手の込んだことはやはり先人たちの知恵を借りると目から鱗が落ちることがしばしば。</p>
<p>それから残念なこととしては少し前にTDDのエントリ出したけどOCUnit使いにくすぎるので結局あんまりやってない始末。<br />
なんかいいテスティングフレームワークないんですかね。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/ios-dev-tips-201006.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iPhone4がやってきた</title>
		<link>http://brass.to/blog/iphone4_has_come.html</link>
		<comments>http://brass.to/blog/iphone4_has_come.html#comments</comments>
		<pubDate>Fri, 25 Jun 2010 17:36:49 +0000</pubDate>
		<dc:creator>akahige</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://brass.to/blog/?p=501</guid>
		<description><![CDATA[ソフトバンクのオンラインショップで予約してた分がやってまいりました。
実は予約してたんです。
システムトラブルで予約できなかった初日があけた翌日の朝方、寝る前になにげなくオンラインショップをのぞいたら予約再開してたのでさ [...]]]></description>
			<content:encoded><![CDATA[<p>ソフトバンクのオンラインショップで予約してた分がやってまいりました。<br />
実は予約してたんです。<br />
システムトラブルで予約できなかった初日があけた翌日の朝方、寝る前になにげなくオンラインショップをのぞいたら予約再開してたのでさくっと。<br />
珍しく勝ち組です。</p>
<p>手持ちの3GSはiSO4にアップグレードしないで待ってたので初のiOS4機だったりもする。<br />
目玉であるマルチタスクの恩恵は今のところ感じない。<br />
すでに起動しているアプリをフォアグラウンドにしても初回起動と同じくスプラッシュが表示されるし、バックグラウンドでの動作をしてくれるアプリもないし、要するに素敵なマルチタスク体験は今のところなし。<br />
まあアプリ側の対応待ちといったところなんでしょう。</p>
<p>開発者的にもiOS4はまだキャッチアップしてないのでしばらくしたらもうちょっと調べなければならないな。</p>
<p>画面のドットが見えないほどの解像度とか、カメラがきれいに撮れるようになってるとか、内蔵スピーカーのパワーがアップしてるとか、ハード的なパワーアップは顕著に感じる。</p>
<p>特にカメラはかなりよくて、単純に画素数が上がっただけじゃなくて撮れる絵がなにやらきれいになってる。<br />
これは旅に出るときなど持って行ってたデジカメがいらない子になってしまったかもしれない。<br />
その場合の心配はバッテリーと手を滑らせて落としてしまわないかと言うことだけども・・・<br />
ストラップがつけられるケースでも買いましょうかね。バッテリ付きも検討ということで。</p>
<p>順調に進化してますます手放せないデバイスになってきた。</p>
]]></content:encoded>
			<wfw:commentRss>http://brass.to/blog/iphone4_has_come.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
