<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>ゆめ技：ゆめみスタッフブログ</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/" />
   <link rel="self" type="application/atom+xml" href="http://yumewaza.yumemi.co.jp/atom.xml" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5</id>
   <updated>2010-08-19T04:21:05Z</updated>
   <subtitle>携帯・モバイルの技術情報はもちろんその他色々な技を発信する株式会社ゆめみの社員によるブログです。</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.33-ja</generator>

<entry>
   <title>SubversionからGitへ移行しようとして日本語ファイル名(UTF8)に困ったことある方に</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/08/git-svn-utf8-filename.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.415</id>
   
   <published>2010-08-19T03:51:20Z</published>
   <updated>2010-08-19T04:21:05Z</updated>
   
   <summary>ファイル名に日本語(UTF8)を含むファイルを、SubversionからWindows上のGitへ移行する方法を実際のコマンド例を示しながら紹介します。最新のCygwin上で動くGitを使えば、文字化けの問題が発生しません。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Git" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="57" label="Git" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[みなさん、こんにちは
kaoruです。


前回に引き続き、Gitに絡んだお話です。


今までSubversionを使っていたけど、そろそろGitに移行しようと考えておられる方も多いのではないでしょうか。


Gitのパッケージの中にgit-svnというモジュールがあるため、SubversionからGitへは比較的容易に移行できます。また、GitからSubversionレポジトリへのコミットも可能なため、一時的に相互運用することも可能になっています。


しかし、ここに大きな落とし穴がありSubversionレポジトリーにドキュメントファイルなど、ファイル名が日本語のファイルがあると文字化けしたりエラーになったりしてうまくいかないのです。


少なくとも以前はそういう状態でした。


しかし、今ではCygwin版Gitを使うという選択肢があります。後ほど、実際にコマンドを実行しながら、日本語のファイル名が文字化けせずに扱えることをご紹介します。


まずは、技術的背景と以前はどのような問題が発生していたかを説明します。


Subversionは内部的にファイル名をUTF8で扱います。
（こちら参照：<a href="http://www.open.collab.net/scdocs/SVNEncoding.html.ja" target="_blank">http://www.open.collab.net/scdocs/SVNEncoding.html.ja</a>）


Git は内部的にファイル名をバイナリ文字列として扱い文字エンコーディングを関知しません。
（こちらのDiscussion参照：<a href="http://www.kernel.org/pub/software/scm/git/docs/v1.7.2.1/git-log.html" target="_blank">http://www.kernel.org/pub/software/scm/git/docs/v1.7.2.1/git-log.html</a>） すなわち、日本語版WindowsではShift_JISになっていました。


Subversionにコミットしたファイルをgit-svnを使って、Git管理に移行すると、ファイル名の文字エンコーディングはUTF8のまま変換しようとしますが、日本語版WindowsではShift_JISでないといけなかったため、問題が発生しました。

<img alt="before.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/before.gif" width="450" height="225" />



しかし、日本語版Windowsでも最新版のCygwinを使えばファイル名をUTF8として扱うことが出来ます。つまり、Cygwin上で動くGitとSubversionは同じUTF8の文字エンコーディングを利用できます。

<img alt="after.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/after.gif" width="450" height="240" />



以下に、実際に試してみた手順を 紹介します。

まず、 Cygwin の最新版と、 Cygwin 版の Git をインストールしました。

バージョン表示は以下のようになります。


<pre>kaoru@ALIEN% uname -a
CYGWIN_NT-6.1-WOW64 ALIEN 1.7.6(0.230/5/3) 2010-08-16 16:06 i686 Cygwin

kaoru@ALIEN% git --version
git version 1.7.1</pre>



影響があるかどうかはわかりませんが、環境変数 LANG は、 UTF8 に設定しました。


<pre>kaoru@ALIEN% echo $LANG
en_US.utf8</pre>



また、 Cygwin に接続する際には putty を利用し、 putty の文字コードの設定は、UTF8 に設定しました。

次に、 git svn clone コマンドで日本語ファイル名を含む Subversion レポジトリーをクローンして Git レポジトリーとしました。

<img alt="yumewaza-git-svn-clone.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/yumewaza-git-svn-clone.gif" width="487" height="162" />




ls -al コマンドで確認しましたが、日本語のファイル名が正しく再現されていることが確認できました。

<img alt="ls-al.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/ls-al.gif" width="449" height="90" />




エクスプローラー上からも文字化けせず日本語ファイル名が利用できました。

<img alt="explorer.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/explorer.gif" width="500" />




次にファイルを変更後、 git status を実行すると、日本語ファイル名がエスケープされて表示されました。

<img alt="git-status-escaped.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/git-status-escaped.gif" width="499" height="120" />




これは少し不便ですので、エスケープしないように設定してみます。

<pre>git config --bool core.quotepath false</pre>

これで、ちゃんとファイル名が読めるように表示されました。

<img alt="git-status.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/git-status.gif" width="470" height="138" />




次に、 git commit で日本語のコミットメッセージを入力してファイルをコミットし、
git log で確認しましたが、正常に表示されました。

<img alt="git-commit.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/git-commit.gif" width="358" height="123" />




最後に、今までの変更を、 Subversion に反映させるために、 git svn dcommit を実行したのですが、筆者の環境ではトラブルが発生し、 unable to remap ... といったエラーメッセージが表示されました。

<img alt="unable_to_remap.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/unable_to_remap.gif" width="488" height="17" />




最初は驚くかもしれませんが、このようなエラーが表示された場合解決策がありますので心配ありません。

まず、 Cygwin から起動したすべてのプロセスを終了させ、通常のコマンドプロンプトから、


<pre>cd C:\cygwin
bin\ash.exe
/bin/rebaseall</pre>

とコマンドを実行すればOKです。

<img alt="rebaseall.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/rebaseall.gif" width="501" height="198" />




作業を再開しましょう。

git svn dcommit コマンドで、 Git レポジトリーの変更を、 Subversion レポジトリに反映し、 svn log -v コマンドで、 Subversion レポジトリのログを確認したところ、日本語のコミットログ、日本語のファイル名のいずれも正しく反映されていることがわかりました。

<img alt="git-svn-dcommit.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/git-svn-dcommit.gif" width="460" height="336" />




以上のような手順により、Cygwin版Gitを利用すれば、Gitで日本語ファイル名を扱うことができ、git-svnを利用することで、Subversionとの連携も可能になることがわかりました。


今まで、日本語のファイル名が原因でSubversionからGitへの移行を躊躇っていたレポジトリについても道が開けたのではないかと思います。



本来Cygwinを使わずに対応したいところなので、もっとスマートな方法を模索中です。より良い方法がありましたら、またご紹介させていただきます。]]>
      
   </content>
</entry>
<entry>
   <title>Gitのちょっと便利な使い方</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/07/git.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.410</id>
   
   <published>2010-07-30T09:38:17Z</published>
   <updated>2010-08-03T04:25:21Z</updated>
   
   <summary>普段はコマンドラインから Git を使っているのに、ブランチ間の関係をビジュアルに表示をするために TortoiseGit や QGit を使っていませんか？ コマンドラインから、わかりやすいブランチグラフの表示をする方法をご紹介します。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Git" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="57" label="Git" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[こんにちは<br />
kaoruです。<br />
<br />
今回は、GitのちょっとしたTipsをご紹介したいと思います。<br />
<br />
Gitというのは、近年、Subversionに代わって普及が進んできたバージョン管理システムです。<br />
<br />
特徴として、Subversionに比べて高速である点と、マージの管理が簡単である点が挙げられます。<br />
<br />
規模の大きな開発や、複数人での開発を行っていると、たくさんのブランチが発生して、ブランチ間の関係をビジュアルに確認したくなることが頻繁にあります。<br />
<br />
TortoiseGitやQGitなどのGUIツールを使うとブランチ間の関係をビジュアルに表示することができます。<br />
<br />
しかし、普段コマンドラインで作業している場合、わざわざ別のツールを使うのではなくコマンドラインで直接確認できた方が便利なのではないでしょうか。<br />
<br />
実は、git logコマンドにはオプションとして、--graphがあり、標準でもツリー表示ができます。しかし、そのままでは、表示される情報が多すぎて、TortoiseGitのような一覧性がよくありません。<br />
<br />
そこで、オプションを工夫してコマンドラインでもビジュアルにブランチ間のツリー構造がビジュアルに確認できるようにしてみました。<br />
<br />
<div style="width: 535px; background-color: #eeeeee; margin: 10px 0; padding: 10px; font-size: small;"><code>
git log --graph --date-order -C -M --pretty=format:\"&lt;%h&gt; %ad [%cn] %Cgreen%d%Creset %s\" --all --date=short
</code></div>
<br />
これを毎回、入力するのはいささか大変ですので、エイリアス機能を使っています。<br />
<br />
以下のような設定を $HOME/.gitconfig か、/etc/gitconfig に追加します。<br />
<div style="width: 535px; background-color: #eeeeee; margin: 10px 0; padding: 10px; font-size: small;"><code>
[alias]<br />
&nbsp;&nbsp;&nbsp;&nbsp;graph = log --graph --date-order -C -M --pretty=format:\"&lt;%h&gt; %ad [%cn] %Cgreen%d%Creset %s\" --all --date=short
</code></div>
(２行目は途中で改行しないようにしてください。）<br />
<br />
このような設定をしておけば、<br />
<pre>
git graph
</pre>
と入力するだけで、表示可能です。<br />
<img style="margin:10pt;" alt="yumewaza-git-screen-capture.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/yumewaza-git-screen-capture.gif" width="142" height="175" />
<br />
<br />
この表示ができると、日々の作業がとても便利になります。<br />
Gitをお使いの方は、是非一度お試しください。<br />
]]>
      
   </content>
</entry>
<entry>
   <title>ファイルディスクリプタ数の上限変更とlimits.confの罠</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/07/limitsconf.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.408</id>
   
   <published>2010-07-26T08:47:42Z</published>
   <updated>2010-07-26T08:50:43Z</updated>
   
   <summary> こんにちは、mikkoです。 今回は、1プロセスが同時オープン可能なファイルデ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="55" label="Apache" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="53" label="Linux" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[
<p>こんにちは、mikkoです。</p>

<p>今回は、1プロセスが同時オープン可能なファイルディスクリプタ数の上限を変更する方法と、その際の落とし穴についてです。</p>

<p>Linuxでは、同時にオープンできるファイルディスクリプタ数が制限されています。<br />
OS全体での設定は、/proc/sys/fs/file-max等で確認でき、大規模なアクセスがあるサーバでは/etc/sysctl.confに設定を追加して上限を増やしているケースも多いでしょう。</p>

<p>これとは別に、1プロセスが同時オープン可能なファイルディスクリプタ数は、標準で1024となっています。<br />
apacheのpreforkモデル等の子プロセスが多数稼動するアプリケーションだと、1プロセスあたりのファイルオープン数はそこまで増加しないので、普段はあまり意識することは少ないかもしれません。<br />
しかし、apacheのworkerモデル等のスレッドを使用するアプリケーションでは、この制限が致命的になるケースが発生します。</p>

<p>では、このファイルディスクリプタ数上限を上げるにはどうすればよいのでしょうか。</p>

<p>1プロセスあたりのファイルディスクリプタ数上限を上げるには3通りあり、</p>
<ol>
  <li>カーネルヘッダファイル中のINR_OPENを書き換えてrebuild</li>
  <li>ulimit -n  で一時的に更新する</li>
  <li>/etc/security/limits.conf に設定を記述する</li>
</ol>
<p>の何れかを選択することになりますが、カーネルのrebuildは手間なので除外すると、選択肢は2つになります。</p>
<blockquote>※プログラム内からsetrlimit()システムコールを呼ぶ方法もありますが、今回は既存のプログラムを扱うことを前提としているので除外します</blockquote>

<h3>ulimitとは何なのか？</h3>
<p>シェルのbuilt-inコマンドで、プロセスに割り当てる各種リソースの制限を行うためのものです（csh系はlimitコマンド）。<br />
ulimit -n を実行すると、現在のファイルディスクリプタ数上限値（SoftLimitおよびHardLimit）が確認できます。<br />
SoftLimitはHardLimit以下の範囲内で一般ユーザが変更可能ですが、HardLimitはrootでしか変更できません。<br />
ulimitを実行したシェルおよび、そのシェルから起動される子プロセスに対して<i><b>一時的に</b></i>設定を変えることが出来ます。</p>

<h3>/etc/security/limits.conf とは何なのか？</h3>
<p>/etc/security/limits.confは、PAM認証モジュールの1つであるpam_limitsの設定ファイルです。</p>
<pre>
&lt;domain&gt; &lt;type&gt; &lt;item&gt; &lt;value&gt;
</pre>
<p>というフォーマットで記述を行い、</p>
<pre>
root soft nofile 2048
root hard nofile 2048
</pre>
<p>と書けば、rootで実行されるプロセス単位の最大ファイルオープン数が2048に設定されます。</p>

<p>pam_limitsモジュールは、PAMの設定ファイル/etc/pam.d/system-auth内においてsession型で定義されており、/etc/pam.d/loginや/etc/pam.d/sshd、/etc/pam.d/sudo等多くの設定ファイルがsystem-authをインクルードする形で使用しています。<br />
従って、先の設定はログイン時やsudo時など、PAM認証が発生する(且つsessionでpam_limitsモジュールがrequireされる)タイミングで有効化されます。</p>

<p>つまり、「<font color="red">PAM認証を介さないようなdaemon系プログラムの制限には/etc/security/limits.confは使えない</font>」ことになるのです。</p>

<p>ところが、googleで「apache limits.conf」等を検索すると、limits.confを書き換えればapacheの上限ファイルディスクリプタ数を増加可能という内容の記事が散見されます。 これはいったいどういうことなのでしょうか？</p>

<h3>罠1：該当ユーザでのulimit -nによる確認</h3>
<p>limits.confに</p>
<pre>
* soft nofile 2048
* hard nofile 2048
</pre>
<p>を記述し、su等でrootになり、ulimit -nを実行して変更確認を行う方法です。</p>

<p>しかし、ログイン時やsu時においてPAM認証が行われた時点でlimits.confの設定が適用されるため、rcスクリプトやdaemontoolsから起動されるプロセスと環境が異なり、確認の意味を成していません。</p>

<h3>罠2：rcスクリプトによる再起動での確認</h3>
<p>実際にdaemonの再起動を行い、'Too many open files'のエラーが出なくなったことを確認する方法です。</p>

<p>実は、rcスクリプトやapachectl等で再起動を行うと、実際に設定が反映されています。<br />
これは非常にわかりにくく、以下のような状況が発生しています。</p>

<p><b>例：</b>sudo /etc/init.d/httpd restart</p>
<ol>
  <li>sudoでrootユーザになる際にPAM認証が行われ、limits.confの設定が適用される（ulimit -n 2048と同義）</li>
  <li>rootユーザで/etc/init.d/httpdを実行する際、上限値が子プロセス(/etc/init.d/httpdはスクリプトなので、bashになる)に引き継がれる</li>
  <li>スクリプト内でhttpdを停止・開始する際、上限値が子プロセス(開始されるhttpd)に引き継がれる</li>
  <li>上限値が引き継がれたhttpdが開始される</li>
</ol>
<p>実際に以下の手順で検証してみました。</p>
<ol>
  <li>1100個のファイルを同時オープンする簡単なphpスクリプト（index.php）を用意</li>
<pre style="width:90%;">
&lt;?php
$fp = array();
for ($i = 0; $i &lt; 1100; $i++) {
    $fp[] = fopen('index.php', 'r');
}
echo '&lt;pre&gt;';
var_dump($fp);
echo '&lt;/pre&gt;';
</pre>
  <li>apache経由でアクセスし、1000個付近でファイルが開けなくなることを確認</li>
<pre style="width:90%;">
...snip...
[999]=&gt;
resource(1002) of type (stream)
[1000]=&gt;
resource(1003) of type (stream)
[1001]=&gt;
bool(false)
[1002]=&gt;
bool(false)
...snip...
</pre>
<blockquote>※ apacheのerror_logにも、'Too many open files'が表示されています。</blockquote>
<blockquote>※ 上限の1024に満たないのは、httpdプロセス自身がいくつか消費しているためです。lsofコマンド等で確認が可能です。</blockquote>
  <li>limits.conf を書き換える</li>
<pre style="width:90%;">
* soft nofile 2048
* hard nofile 2048
</pre>
  <p>を追加する。</p>
  <li>sudo /etc/init.d/httpd restartでapacheを再起動する</li>
  <li>再度apache経由でアクセスし、1000個以上ファイルが開けることを確認</li>
  <blockquote>※ ここまでで、上限値が反映されたと誤解してしまいます！</blockquote>
  <li>マシンを再起動する</li>
  <li>三度apache経由でアクセスし、1000個付近でファイルが開けなくなることを確認</li>
  <blockquote>※ 上限値が1024に戻ってしまいます！</blockquote>
</ol>

<p>つまり、手動で再起動した場合は<i><b>一時的に</b></i>limits.confの設定内容が有効になるだけなのです。<br />
当然、マシン自体が再起動した場合はinitが各daemonを起動し、PAM認証が入らないため、OS規定の上限値である1024に戻ってしまいます。 </p>

<p>結局、リミット値を上げるには、ulimit -n の記述を
<ul>
  <li>daemontoolsであれば、/service/&lt;サービス名&gt;/runファイルに追加</li>
  <li>rcスクリプトであれば、/etc/init.d/&lt;サービス名&gt;ファイルに追加</li>
</ul>
<p>しないといけません。 </p>

<p>ただしapacheの場合、apachectl経由での制御を行うとrcスクリプトを介さないため、apachectlにも追加しておかないといけないことに注意してください。</p>
<ul>
  <li>apachectl restart</li>
  <p>既存のhttpdプロセスにシグナルを送り、既存httpdから新規httpdがforkされるため、既存httpdのリミット値が引き継がれます。</p>
  <li>apachectl start</li>
  <p>新規httpdが起動され、上記rcスクリプトの実行の流れと同じ現象が起こるため、ulimitの追加が必要です。</p>
</ul>

<h3>結論</h3>
<p>daemon系プロセスのファイルディスクリプタ数上限を設定する際、/etc/security/limits.conf は使えません。状況によっては一見設定されたように見えますが、大きな落とし穴にはまることになります。<br />
面倒ですが、必要なプロセス毎にulimitを用いて適切に設定しましょう。</p>]]>
      
   </content>
</entry>
<entry>
   <title>コンパイル言語 C++ とスクリプト言語 Lua を、Luabind を使って組み合わせてみる</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/06/_c_lua_luabind.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.401</id>
   
   <published>2010-06-25T07:22:41Z</published>
   <updated>2010-08-02T10:42:38Z</updated>
   
   <summary>Lua は近年ゲーム業界などを中心に急速に普及してきている軽量なスクリプト言語です。 C++ から、Boost.Python とよく似た Luabind ライブラリーを利用して Lua スクリプトと相互にオブジェクトをやりとりする方法をご紹介します。サンプルプログラムもたくさん用意しましたので、初心者の方にも入門として参考なればと思います。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Lua" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="41" label="Boost" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="43" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="45" label="C++0x" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="47" label="Lua" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="49" label="Luabind" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>みなさん、こんにちは。<br />
kaoruです。</p>

<p>今回は、コンパイル言語 C++ とスクリプト言語 Lua を、Luabind というライブラリーで使って組み合わせて利用する方法を紹介します。</p>

<h3>はじめに</h3>
<p>まず、C++とLuaを組み合わせようという背景を説明したいと思います。</p>

<p>両者を比較するポイントとして、コンパイル言語かスクリプト言語かという点が重要な要素になります。</p>

<p>コンパイル言語とスクリプト言語の特徴を挙げてみました。</p>

コンパイル言語（C++, JAVAなど）<br />
<ul>
    <li>コンパイル時に全ての変数の型の整合性がチェックされるので堅牢</li>
    <li>大きなデータを効率的に扱える</li>
    <li>実行速度が速い</li>
    <li>一度作ってしまえば再利用が容易</li>
</ul>

スクリプト言語（Lua、Python、PHPなど）<br />
<ul>
    <li>型が動的で柔軟</li>
    <li>コンパイルやインストール、システム再起動などの前準備せずに動作確認が可能</li>
    <li>コーディング量が少なく、試行錯誤が簡単</li>
    <li>再利用できるように作るには工夫が必要</li>
</ul>

<p>コンパイル言語とスクリプト言語では、得意分野が大きく違うのです。</p>

<p>そこで、それぞれの得意分野を生かしながら両方を組み合わせて開発をすることでよりよいものを作ることができます。</p>

<p>今回取り上げるLuabindはC++とLuaの間の橋渡しをするためのライブラリーです。</p>

<h3>Luaを使ってみよう</h3>

<p>読者の中には、Luaを使ったことがない方もいらっしゃると思いますので、雰囲気をご紹介したいと思います。</p>

<h5>Hello worldを作ってみよう</h5>

<p>Luaはほかのアプリケーションの中に組み込んで使うことが多いのですが、単体でも動作します。</p>

<p>画面にテキストを表示するだけなら１行から書けます。</p>

<pre>
print "Hello world"
</pre>

<p>簡単ですね。Luaは行末にセミコロンを書かなくてもOKです。</p>

<h5>文とブロック</h5>

<p>PHPなどでは、{ と } でブロックを囲みますが、Lua では do と end などで囲みます。</p>

<pre>
do
    local a = 123
    print a
end
</pre>

<h5>四則演算と式</h5>

<p>PHPなどほかの言語に比べると、!= がなくて、かわりに ~= と書かないといけないなど、微妙な違いはありますが、慣れるとあまり大きな違いはありません。</p>

<pre>
do
    local a, b = 1, 2
    if a ~= b then
        print "Mismatch"
    end
end
</pre>

<p>さらにメタテーブルという機能を使うと、オブジェクト同士の演算などをカスタマイズできるので、C++のoperatorと感覚が似ていて面白そうです。</p>

<h5>関数の定義</h5>

<p>関数の定義はJavascriptとよく似ています。ラムダ式も使えます。</p>
<pre>
function make_less_than(b)
    return function less_than(a)
              return a < b
           end
end
</pre>

<h3>Luabindを使ってみる</h3>
<p>簡単に使い方を紹介します。</p>

<p>Luabind / Lua のインクルードファイルをロードします。</p>
<PRE><FONT COLOR="#000099">#include &lt;luabind/lua_include.hpp&gt;
#include &lt;luabind/luabind.hpp&gt;
</FONT></PRE>

<p>まず、Luaステートオブジェクトを作成します。</p>
<pre>
lua_State* L = lua_open();
</pre>

<p>lua.hをみると、lua_open()関数はマクロでluaL_newstate()関数に置換されるため、luaL_newstate()関数を直接呼んでもよさそうです。</p>

<p>ここで作成したオブジェクトは、使い終わったら、lua_close(L)関数でクローズしなければいけません。C++では、自分で閉じるのではなく、RAIIクラスやスマートポインターを使って自動的にリソース管理するほうがよいでしょう。</p>

<p>次に標準ライブラリーをロードします。</p>
<pre>
luaL_openlibs(L);
</pre>

<p>この関数をロードするためには追加のインクルードファイルが必要かもしれません。</p>
<PRE><FONT COLOR="#990000">extern</FONT><FONT COLOR="#009900"> "C"</FONT><B><FONT COLOR="#663300"> {</FONT></B><FONT COLOR="#000099">
    #include "lualib.h"
</FONT><B><FONT COLOR="#663300">}</FONT></B>
</PRE>

<p>Luabindを使う場合は、Luabindの初期化も忘れないように行わなければいけません。忘れるとアプリケーションがクラッシュしてしまいます。</p>
<pre>
luabind::open(L);
</pre>


<h5>Luabindによる疑似クラス</h5>

<p>Luaにはクラスの言語サポートはありませんが、メタテーブルなどの柔軟な言語機能を用いて、クラス相当のものをライブラリーで作ることができます。
今回はLuabindの機能を使ってクラスを作ってみました(<b>yumewaza.cpp</b>, <b>sample.lua</b>)。luabind::open(L)を呼び出すと、class, propertyやsuperなどのキーワードが登録され利用できるようになります。
</p>

<b><u>yumewaza.cpp</u></b><br />
<pre><font color="#000099">#include &lt;string&gt;
#include &lt;sstream&gt;
#include &lt;iostream&gt;
#include &lt;luabind/lua_include.hpp&gt;
#include &lt;luabind/luabind.hpp&gt;
</font><font color="#990000">

extern</font><font color="#009900"> "C"</font><b><font color="#663300"> {</font></b><font color="#000099">
    #include "lualib.h"
</font><b><font color="#663300">}</font></b><font color="#ff6633">

int</font><font color="#990000"> main</font><b><font color="#663300">(</font></b><font color="#ff6633">int</font> argc<b><font color="#663300">,</font></b><font color="#990000"> const</font><font color="#ff6633"> char</font><b><font color="#663300"> *</font></b>argv<b><font color="#663300">[])
{</font></b><font color="#ff0000">

    if</font><b><font color="#663300"> (</font></b>argc<b><font color="#663300"> !=</font></b><font color="#999900"> 2</font><b><font color="#663300">) {</font></b>
        std<b><font color="#663300">::</font></b>cerr<b><font color="#663300"> &lt;&lt;</font></b> argv<b><font color="#663300">[</font></b><font color="#999900">0</font><b><font color="#663300">] &lt;&lt;</font></b><font color="#009900"> " &lt;script file.lua&gt;"</font><b><font color="#663300"> &lt;&lt;</font></b> std<b><font color="#663300">::</font></b>endl<b><font color="#663300">;</font></b><font color="#ff0000">

        return</font><font color="#999900"> 1</font><b><font color="#663300">;
    }</font></b>

    lua_State<b><font color="#663300">*</font></b> L<b><font color="#663300"> =</font></b> lua_open<b><font color="#663300">();</font></b>

    luaL_openlibs<b><font color="#663300">(</font></b>L<b><font color="#663300">);</font></b>

    luabind<b><font color="#663300">::</font></b>open<b><font color="#663300">(</font></b>L<b><font color="#663300">);</font></b><font color="#ff0000">

    if</font><b><font color="#663300"> (</font></b>luaL_dofile<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> argv<b><font color="#663300">[</font></b><font color="#999900">1</font><b><font color="#663300">])) {</font></b>

        std<b><font color="#663300">::</font></b>cerr<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "ERROR : "</font><b><font color="#663300"> &lt;&lt;</font></b> lua_tostring<b><font color="#663300">(</font></b>L<b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">) &lt;&lt;</font></b> std<b><font color="#663300">::</font></b>endl<b><font color="#663300">;</font></b>

        lua_close<b><font color="#663300">(</font></b>L<b><font color="#663300">);</font></b><font color="#ff0000">
        return</font><font color="#999900"> 1</font><b><font color="#663300">;
    }</font></b>

    lua_close<b><font color="#663300">(</font></b>L<b><font color="#663300">);</font></b><font color="#ff0000">

    return</font><font color="#999900"> 0</font><b><font color="#663300">;
}</font></b>
</pre>
<br />
<b><u>sample.lua</u></b><br />
<pre>
-- 継承元がない独立したクラス MyClass
class 'MyClass'
    -- コンストラクター
    function MyClass:__init()
        self.var_a = 1
    end

    -- 関数１
    function MyClass:func01()
        print("MyClass:func01()")
    end

    -- 関数２
    function MyClass:func02()
        print("MyClass:func02()")
        self.var_a = self.var_a + 1
    end

-- MyClass を継承したクラス MyClass2
class 'MyClass2' (MyClass)
    -- コンストラクター
    function MyClass2:__init()
        MyClass.__init(self)
    end

    -- オーラーライドされた関数２
    function MyClass2:func02()
        MyClass.func02(self)
        print("MyClass2:func02()")
        self.var_a = -self.var_a
    end

do
    print "---------- test01 ---------"
    local obj01 = MyClass()
    print(string.format("self.var_a = %d", obj01.var_a))
    obj01:func01()
    print(string.format("self.var_a = %d", obj01.var_a))
    obj01:func02()
    print(string.format("self.var_a = %d", obj01.var_a))

    print "---------- test02 ---------"
    local obj02 = MyClass2()
    print(string.format("self.var_a = %d", obj02.var_a))
    obj02:func01()
    print(string.format("self.var_a = %d", obj02.var_a))
    obj02:func02()
    print(string.format("self.var_a = %d", obj02.var_a))
end
</pre>

<b>sample.luaの実行例</b><br />
<code>
---------- test01 ---------<br />
self.var_a = 1<br />
MyClass:func01()<br />
self.var_a = 1<br />
MyClass:func02()<br />
self.var_a = 2<br />
---------- test02 ---------<br />
self.var_a = 1<br />
MyClass:func01()<br />
self.var_a = 1<br />
MyClass:func02()<br />
MyClass2:func02()<br />
self.var_a = -2<br />
</code>

<p>サンプルに示すように、classキーワードを使うことで、本当のクラスのように定義が書けるほか、継承や、メソッドのオーバーライドも可能になります。
自分で独自にクラス機構を実装することもできますが、Luabindを使っている場合は、ぜひ利用してみてはどうでしょうか。
</p>

<h3>C++のクラスや構造体をLuaで使う</h3>

<p>C++のクラスや構造体をLua側で使えるように登録するには次のようにします。</p>
<p>例として次の構造体がC++側であるとします。</p>
<pre><font color="#990000">struct</font> my_struct_t<b><font color="#663300">
{</font></b><font color="#ff6633">
    int</font> var_a<b><font color="#663300">;</font></b>
    std<b><font color="#663300">::</font></b>string var_b<b><font color="#663300">;</font></b>

    boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;</font></b> var_c<b><font color="#663300">;</font></b><font color="#ff6633">

    void</font> method_a<b><font color="#663300">();</font></b><font color="#ff6633">

    int</font> method_b<b><font color="#663300">();</font></b>
    std<b><font color="#663300">::</font></b>string method_c<b><font color="#663300">();
};</font></b>
</pre>

<p>これをLua側で使えるようにLuabindを使って登録してみます。</p>
<PRE>luabind<B><FONT COLOR="#663300">::</FONT></B>module<B><FONT COLOR="#663300">(</FONT></B>L<B><FONT COLOR="#663300">)
[</FONT></B>
    luabind<B><FONT COLOR="#663300">::</FONT></B>class_<B><FONT COLOR="#663300">&lt;</FONT></B>my_struct_t<B><FONT COLOR="#663300">&gt;(</FONT></B><FONT COLOR="#009900">"my_struct_t"</FONT><B><FONT COLOR="#663300">)
        .</FONT></B>def_readwrite<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"var_a"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>var_a<B><FONT COLOR="#663300">)
        .</FONT></B>def_readwrite<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"var_b"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>var_b<B><FONT COLOR="#663300">)
        .</FONT></B>def_readwrite<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"var_c"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>var_c<B><FONT COLOR="#663300">)
        .</FONT></B>def<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"method_a"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>method_a<B><FONT COLOR="#663300">)
        .</FONT></B>def<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"method_b"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>method_b<B><FONT COLOR="#663300">)
        .</FONT></B>def<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"method_c"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>my_struct_t<B><FONT COLOR="#663300">::</FONT></B>method_c<B><FONT COLOR="#663300">)
];</FONT></B>
</PRE>

<h3>C++のフリー関数をLuaで使う</h3>

<p>あるいは、C++のフリー関数をLua側で使えるように登録するには次のようにします。</p>
<p>C++側で、次のようなフリー関数があったとすると</p>
<pre>my_struct_t create_my_object<b><font color="#663300">()
{</font></b><font color="#ff0000">
    return</font> my_struct_t<b><font color="#663300">();
}</font></b>
</pre>

<p>Lua側で使えるようにするには、次のようにします。</p>
<PRE>luabind<B><FONT COLOR="#663300">::</FONT></B>module<B><FONT COLOR="#663300">(</FONT></B>L<B><FONT COLOR="#663300">)
[</FONT></B>
    luabind<B><FONT COLOR="#663300">::</FONT></B>def<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#009900">"create_my_object"</FONT><B><FONT COLOR="#663300">, &amp;</FONT></B>create_my_object<B><FONT COLOR="#663300">)
];</FONT></B>
</PRE>

<h3>C++からLuaスクリプトを実行</h3>

<p>このような準備をした後、luaL_dostring関数を使えば、Luaのスクリプトを文字列で渡して実行できます。</p>

<pre>    luaL_dostring<b><font color="#663300">(</font></b>lua_state<b><font color="#663300">.</font></b>get<b><font color="#663300">(),</font></b><font color="#009900">
        "function set_a(obj, value) \n"
        "    obj.var_a = value      \n"
        "end                        \n"</font><b><font color="#663300">
    );</font></b>
</pre>

<h3>C++からLuaスクリプトファイルをロードして実行する</h3>

<p>あるいは、Luaスクリプトをファイルからロードするには次のようにします。</p>
<pre><font color="#ff0000">if</font><b><font color="#663300"> (</font></b>luaL_dofile<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b><font color="#009900"> "script.lua"</font><b><font color="#663300">)) {</font></b>
    std<b><font color="#663300">::</font></b>cerr<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "ERROR : "</font><b><font color="#663300"> &lt;&lt;</font></b> lua_tostring<b><font color="#663300">(</font></b>L<b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">) &lt;&lt;</font></b> std<b><font color="#663300">::</font></b>endl<b><font color="#663300">;</font></b>

    BOOST_ASSERT<b><font color="#663300">(</font></b><b><font color="#000000"> false</font></b><b><font color="#663300"> );
}</font></b>
</pre>

<h3>Luaの関数をC++から呼び出す</h3>

<p>また、Luaスクリプトの中で定義されている関数をC++側から直接呼び出すこともできます。</p>
<pre>my_struct_t obj<b><font color="#663300">;</font></b>
luabind<b><font color="#663300">::</font></b>call_function<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">&gt;(</font></b>
    L<b><font color="#663300">,</font></b><font color="#009900">
    "set_a"</font><b><font color="#663300">,</font></b>

    boost<b><font color="#663300">::</font></b>ref<b><font color="#663300">(</font></b>obj<b><font color="#663300">),</font></b><font color="#999900">
    123</font><b><font color="#663300">
);</font></b>
</pre>

<p>呼び出されるLua側のソースコードは例えば次のようになります。</p>
<pre>
function set_a(obj, value)
    obj.var_a = value
end
</pre>

<h3>Lua側でC++側の変数の値を変更するには</h3>

<p>ここで、objをそのまま渡さずに、boost::ref(obj)としているのは、objをそのまま渡してしまうと、objのコピーが作成されて、それがLua側に渡されるために、Lua側でオブジェクトのプロパティーを書き換えても、呼び出し元のobj変数は変更されないからです。</p>

<p>boost::refを利用すると、参照としてLua側にオブジェクトを引き渡せるので、Lua側での変更が、きちんと、C++側に反映されます。</p>

<h3>Luaの文字列/nilをboost::optionalを使って扱う</h3>

<p>また、数値や文字列だけではなく、nilをC++とLuaでやりとりしたい場合もあると思います。</p>

<p>今回は、boost::optionalを使ってC++側でnilを表現することにしました。それには、LuaとC++の双方で型をコンバートする方法をLuabindに教える必要があります。</p>
<pre><font color="#000099">#include &lt;string&gt;
#include &lt;boost/optional/optional.hpp&gt;
#include &lt;luabind/lua_include.hpp&gt;
#include &lt;luabind/luabind.hpp&gt;
</font><font color="#990000">
namespace</font> luabind<b><font color="#663300">

{</font></b><font color="#990000">
    template</font><b><font color="#663300"> &lt;&gt;</font></b><font color="#990000">
    struct</font> default_converter<b><font color="#663300">&lt;</font></b>boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;&gt;

      :</font></b> native_converter_base<b><font color="#663300">&lt;</font></b>boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;&gt;
    {</font></b><font color="#990000">
        static</font><font color="#ff6633"> int</font> compute_score<b><font color="#663300">(</font></b>lua_State<b><font color="#663300">*</font></b> L<b><font color="#663300">,</font></b><font color="#ff6633"> int</font> index<b><font color="#663300">)
        {</font></b><font color="#990000">

            using namespace</font> std<b><font color="#663300">;</font></b><font color="#ff0000">

            switch</font><b><font color="#663300"> (</font></b>lua_type<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> index<b><font color="#663300">))
            {</font></b><font color="#ff0000">

                case</font> LUA_TNIL<b><font color="#663300">:</font></b><font color="#ff0000">
                case</font> LUA_TSTRING<b><font color="#663300">:</font></b><font color="#ff0000">
                    return</font><font color="#999900"> 0</font><b><font color="#663300">;</font></b><font color="#ff0000">

                default</font><b><font color="#663300">:</font></b><font color="#ff0000">
                    return</font><b><font color="#663300"> -</font></b><font color="#999900">1</font><b><font color="#663300">;
            }
        }</font></b>

        boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;</font></b> from<b><font color="#663300">(</font></b>lua_State<b><font color="#663300">*</font></b> L<b><font color="#663300">,</font></b><font color="#ff6633"> int</font> index<b><font color="#663300">)
        {</font></b><font color="#990000">

            using namespace</font> std<b><font color="#663300">;</font></b><font color="#ff0000">

            switch</font><b><font color="#663300"> (</font></b>lua_type<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> index<b><font color="#663300">))
            {</font></b><font color="#ff0000">

                case</font> LUA_TNIL<b><font color="#663300">:</font></b><font color="#ff0000">
                    return</font> boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;();</font></b><font color="#ff0000">

                case</font> LUA_TSTRING<b><font color="#663300">:</font></b><font color="#ff0000">
                default</font><b><font color="#663300">:</font></b><font color="#ff0000">
                    return</font> string<b><font color="#663300">(</font></b>lua_tostring<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> index<b><font color="#663300">));
            }
        }</font></b><font color="#ff6633">

        void</font> to<b><font color="#663300">(</font></b>lua_State<b><font color="#663300">*</font></b> L<b><font color="#663300">,</font></b> boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;</font></b><font color="#990000"> const</font><b><font color="#663300">&amp;</font></b> x<b><font color="#663300">)
        {</font></b><font color="#990000">

            using namespace</font> std<b><font color="#663300">;</font></b><font color="#ff0000">

            if</font><b><font color="#663300"> (</font></b>x<b><font color="#663300">)</font></b>
                lua_pushstring<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> x<b><font color="#663300">-&gt;</font></b>c_str<b><font color="#663300">());</font></b><font color="#ff0000">

            else</font>
                lua_pushnil<b><font color="#663300">(</font></b>L<b><font color="#663300">);
        }
    };</font></b><font color="#990000">

    template</font><b><font color="#663300"> &lt;&gt;</font></b><font color="#990000">
    struct</font> default_converter<b><font color="#663300">&lt;</font></b>boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;</font></b><font color="#990000"> const</font><b><font color="#663300">&amp;&gt;

      :</font></b> default_converter<b><font color="#663300">&lt;</font></b>boost<b><font color="#663300">::</font></b>optional<b><font color="#663300">&lt;</font></b>std<b><font color="#663300">::</font></b>string<b><font color="#663300">&gt;&gt;
    {};
}</font></b>
</pre>

<p>今回は、boost::optional<std::string>とLuaの文字列/nilを相互に変換していますが、C++の他の型をLuaとやりとりする方法を定義する参考になればと思います。</p>

<h3>Luaスクリプト中で発生したエラー情報の取得</h3>

<p>デフォルトではLuaスクリプトにエラーがある場合、あまり情報を取得することができませんが、luabind::set_pcall_callback というメソッドでエラーハンドラーを指定することができます。</p>

<p>今回、サンプルを作ってみました。</p>

<pre><font color="#ff6633">int</font> lua_error_handler<b><font color="#663300">(</font></b>lua_State<b><font color="#663300">*</font></b> L<b><font color="#663300">)
{</font></b>
    lua_Debug d<b><font color="#663300"> = {};</font></b>
    std<b><font color="#663300">::</font></b>stringstream msg<b><font color="#663300">;</font></b><i><font color="#999999">

    // スタックからエラーメッセージを取得する
</font></i>    std<b><font color="#663300">::</font></b>string err<b><font color="#663300"> =</font></b> lua_tostring<b><font color="#663300">(</font></b>L<b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">);</font></b>

    msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "ERROR: "</font><b><font color="#663300"> &lt;&lt;</font></b> err<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "\n\nBacktrace:\n"</font><b><font color="#663300">;</font></b><font color="#ff0000">

    for</font><b><font color="#663300"> (</font></b><font color="#ff6633">int</font> stack_depth<b><font color="#663300"> =</font></b><font color="#999900"> 1</font><b><font color="#663300">;</font></b> lua_getstack<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> stack_depth<b><font color="#663300">, &amp;</font></b>d<b><font color="#663300">); ++</font></b>stack_depth<b><font color="#663300">) {</font></b>

        lua_getinfo<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b><font color="#009900"> "Sln"</font><b><font color="#663300">, &amp;</font></b>d<b><font color="#663300">);</font></b>

        msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "#"</font><b><font color="#663300"> &lt;&lt;</font></b> stack_depth<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> " "</font><b><font color="#663300">;</font></b><font color="#ff0000">

        if</font><b><font color="#663300"> (</font></b>d<b><font color="#663300">.</font></b>name<b><font color="#663300">)</font></b>
            msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "&lt;"</font><b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>namewhat<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "&gt; \""</font><b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>name<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "\""</font><b><font color="#663300">;</font></b><font color="#ff0000">

        else</font>
            msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "--"</font><b><font color="#663300">;</font></b>

        msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> " (called"</font><b><font color="#663300">;</font></b><font color="#ff0000">

        if</font><b><font color="#663300"> (</font></b>d<b><font color="#663300">.</font></b>currentline<b><font color="#663300"> &gt;</font></b><font color="#999900"> 0</font><b><font color="#663300">)</font></b>
            msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> " at line "</font><b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>currentline<b><font color="#663300">;</font></b>

        msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> " in "</font><b><font color="#663300">;</font></b><font color="#ff0000">
        if</font><b><font color="#663300"> (</font></b>d<b><font color="#663300">.</font></b>linedefined<b><font color="#663300"> &gt;</font></b><font color="#999900"> 0</font><b><font color="#663300">)</font></b>

            msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> "function block between line "</font><b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>linedefined<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> ".."</font><b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>lastlinedefined<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> " of "</font><b><font color="#663300">;</font></b>

        msg<b><font color="#663300"> &lt;&lt;</font></b> d<b><font color="#663300">.</font></b>short_src<b><font color="#663300">;</font></b>
        msg<b><font color="#663300"> &lt;&lt;</font></b><font color="#009900"> ")\n"</font><b><font color="#663300">;
    }</font></b><i><font color="#999999">

    // スタックに積まれているエラーメッセージを、新しい文字列に置換する。
</font></i>    lua_pop<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b><font color="#999900"> 1</font><b><font color="#663300">);</font></b>
    lua_pushstring<b><font color="#663300">(</font></b>L<b><font color="#663300">,</font></b> msg<b><font color="#663300">.</font></b>str<b><font color="#663300">().</font></b>c_str<b><font color="#663300">());</font></b>

    std<b><font color="#663300">::</font></b>cout<b><font color="#663300"> &lt;&lt;</font></b> msg<b><font color="#663300">.</font></b>str<b><font color="#663300">() &lt;&lt;</font></b> std<b><font color="#663300">::</font></b>endl<b><font color="#663300">;</font></b><font color="#ff0000">

    return</font><font color="#999900"> 1</font><b><font color="#663300">;
}</font></b>

luabind<b><font color="#663300">::</font></b>set_pcall_callback<b><font color="#663300">(</font></b>lua_error_handler<b><font color="#663300">);</font></b></pre>

<p>実行例を、以下に示します。</p>

<code>
ERROR: [string "function _set_a(obj, value) ..."]:2: attempt to index field 'var_a' (a number value)<br />
<br />
Backtrace:<br />
#1 &lt;global&gt; "_set_a" (called at line 2 in function block between line 1..3 of [string "function _set_a(obj, value) ..."])<br />
#2 -- (called at line 5 in function block between line 4..6 of [string "function _set_a(obj, value) ..."])<br />
</code>

<p>１行目にエラーの内容（この例では、var_aは数値であるのに、インデックスフィールドが参照された旨が示されている。）が表示され、
Backtrace:の次の行から、呼び出し履歴が表示されています。＃１によると、エラーの個所はグローバル関数の_set_aの中の２行目（それはLuaスクリプトとして渡された文字列の１?３行目で定義されている。）から呼び出されていることが分かり、＃２によると、それは、５行目から呼び出されていることがわかります。
</p>
<p>
このようにエラーハンドラーを設定することで、エラーが発生した場所や、スクリプトのファイル名、関数の呼び出し履歴などを取得し、表示することができます。
</p>

<h3>Luabind がVS2010でコンパイルエラーになる場合には・・・</h3>

<p>余談ですが、筆者の環境ではVisual Studio 2010でLuabindがコンパイルエラーになったため、Luabindのソースコードを若干変更しました。</p>
<p>具体的には、std::pairのコンストラクターを呼び出している個所で、C++0xに関連して、0の扱いがあいまいになってしまいコンパイルエラーになっていたので、明示的なキャストをして問題を解決しました。</p>

<pre>diff<b><font color="#663300"> --</font></b>git a<b><font color="#663300">/</font></b>luabind<b><font color="#663300">/</font></b>lua_include<b><font color="#663300">.</font></b>hpp b<b><font color="#663300">/</font></b>luabind<b><font color="#663300">/</font></b>lua_include<b><font color="#663300">.</font></b>hpp
index 899df14<b><font color="#663300">..</font></b>368b61a<font color="#999900"> 100755</font><b><font color="#663300">

---</font></b> a<b><font color="#663300">/</font></b>luabind<b><font color="#663300">/</font></b>lua_include<b><font color="#663300">.</font></b>hpp<b><font color="#663300">
+++</font></b> b<b><font color="#663300">/</font></b>luabind<b><font color="#663300">/</font></b>lua_include<b><font color="#663300">.</font></b>hpp
@@<b><font color="#663300"> -</font></b><font color="#999900">25</font><b><font color="#663300">,</font></b><font color="#999900">8</font><b><font color="#663300"> +</font></b><font color="#999900">25</font><b><font color="#663300">,</font></b><font color="#999900">8</font> @@<font color="#990000">

 extern</font><font color="#009900"> "C"</font><b><font color="#663300">
 {
-</font></b>       #include<font color="#009900"> "lua.h"</font><b><font color="#663300">
-</font></b>       #include<font color="#009900"> "lauxlib.h"</font><b><font color="#663300">

+</font></b>       #include<b><font color="#663300"> &lt;</font></b>lua<b><font color="#663300">.</font></b>h<b><font color="#663300">&gt;
+</font></b>       #include<b><font color="#663300"> &lt;</font></b>lauxlib<b><font color="#663300">.</font></b>h<b><font color="#663300">&gt;
 }</font></b><font color="#000099">

 #endif
</font>diff<b><font color="#663300"> --</font></b>git a<b><font color="#663300">/</font></b>src<b><font color="#663300">/</font></b>inheritance<b><font color="#663300">.</font></b>cpp b<b><font color="#663300">/</font></b>src<b><font color="#663300">/</font></b>inheritance<b><font color="#663300">.</font></b>cpp
index 45daeb8<b><font color="#663300">..</font></b>4c7293b<font color="#999900"> 100644</font><b><font color="#663300">

---</font></b> a<b><font color="#663300">/</font></b>src<b><font color="#663300">/</font></b>inheritance<b><font color="#663300">.</font></b>cpp<b><font color="#663300">
+++</font></b> b<b><font color="#663300">/</font></b>src<b><font color="#663300">/</font></b>inheritance<b><font color="#663300">.</font></b>cpp
@@<b><font color="#663300"> -</font></b><font color="#999900">154</font><b><font color="#663300">,</font></b><font color="#999900">7</font><b><font color="#663300"> +</font></b><font color="#999900">154</font><b><font color="#663300">,</font></b><font color="#999900">7</font> @@ std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;</font></b> cast_graph<b><font color="#663300">::</font></b>impl<b><font color="#663300">::</font></b>cast<b><font color="#663300">(</font></b><font color="#ff0000">

     if</font><b><font color="#663300"> (</font></b>cached<b><font color="#663300">.</font></b>first<b><font color="#663300"> !=</font></b> cache<b><font color="#663300">::</font></b>unknown<b><font color="#663300">)
     {</font></b><font color="#ff0000">
         if</font><b><font color="#663300"> (</font></b>cached<b><font color="#663300">.</font></b>first<b><font color="#663300"> ==</font></b> cache<b><font color="#663300">::</font></b>invalid<b><font color="#663300">)
-</font></b><font color="#ff0000">            return</font> std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;(</font></b><font color="#999900">0</font><b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">);
+</font></b><font color="#ff0000">            return</font> std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;(</font></b><font color="#990000">static_cast</font><b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300"> *&gt;(</font></b><font color="#999900">0</font><b><font color="#663300">), -</font></b><font color="#999900">1</font><b><font color="#663300">);</font></b><font color="#ff0000">

         return</font> std<b><font color="#663300">::</font></b>make_pair<b><font color="#663300">((</font></b><font color="#ff6633">char</font><b><font color="#663300">*)</font></b>p<b><font color="#663300"> +</font></b> cached<b><font color="#663300">.</font></b>first<b><font color="#663300">,</font></b> cached<b><font color="#663300">.</font></b>second<b><font color="#663300">);
     }</font></b>

@@<b><font color="#663300"> -</font></b><font color="#999900">192</font><b><font color="#663300">,</font></b><font color="#999900">7</font><b><font color="#663300"> +</font></b><font color="#999900">192</font><b><font color="#663300">,</font></b><font color="#999900">7</font> @@ std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;</font></b> cast_graph<b><font color="#663300">::</font></b>impl<b><font color="#663300">::</font></b>cast<b><font color="#663300">(</font></b>

     m_cache<b><font color="#663300">.</font></b>put<b><font color="#663300">(</font></b>src<b><font color="#663300">,</font></b> target<b><font color="#663300">,</font></b> dynamic_id<b><font color="#663300">,</font></b> object_offset<b><font color="#663300">,</font></b> cache<b><font color="#663300">::</font></b>invalid<b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">);

-</font></b><font color="#ff0000">    return</font> std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;(</font></b><font color="#999900">0</font><b><font color="#663300">, -</font></b><font color="#999900">1</font><b><font color="#663300">);
+</font></b><font color="#ff0000">    return</font> std<b><font color="#663300">::</font></b>pair<b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300">*,</font></b><font color="#ff6633"> int</font><b><font color="#663300">&gt;(</font></b><font color="#990000">static_cast</font><b><font color="#663300">&lt;</font></b><font color="#ff6633">void</font><b><font color="#663300"> *&gt;(</font></b><font color="#999900">0</font><b><font color="#663300">), -</font></b><font color="#999900">1</font><b><font color="#663300">);
 }</font></b><font color="#ff6633">

 void</font> cast_graph<b><font color="#663300">::</font></b>impl<b><font color="#663300">::</font></b>insert<b><font color="#663300">(</font></b>
</pre>

<h3>おわりに</h3>

<p>駆け足で、紹介してきましたが、C++とLua、Luabindを利用した開発のイメージはつかめましたでしょうか。コンパイル言語での開発の中にスクリプト言語を取り入れると、自由度が上がり、開発の幅が広がりますので、ご興味のある方は一度試してみられるといいと思います。</p>
<p>LuaのAPIをC言語から呼び出す際には、Luaスタックを介してやりとりをしなければいけないので、
少々面倒くさい面があるのですが、C++からLuabindを利用すると、Luaスタックの操作はほとんど
ライブラリー側で面倒をみてくれるので、本当にやりたいことだけを書けばよくなっています。
</p>
<p>まだまだ、書ききれなかったことはたくさんありますが、LuaやLuabindのオフィシャルサイトの他、最近は、ユーザーのブログや書籍もたくさんありますので、困った時にはいろいろと探してみるといいかもしれません。</p>
<p>
最後に、オフィシャルサイトのリンクを掲載しておきます。
</p>
<p><a href="http://www.lua.org/" target="_blank">http://www.lua.org/</a><br/>
Luaのサイト　最新のLuaがダウンロードできます</p>

<p><a href="http://www.rasterbar.com/products/luabind.html" target="_blank">http://www.rasterbar.com/products/luabind.html</a><br />
Luabindのサイト　最新のLuabindがダウンロードできるほか、ドキュメントがとても参考になります。</p>]]>
      
   </content>
</entry>
<entry>
   <title>PhotoShop・Illustrator CS5 からWeb用に保存したファイルが一部携帯端末で見れない場合</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/06/cs5_meta.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.394</id>
   
   <published>2010-06-08T11:29:04Z</published>
   <updated>2010-07-05T02:53:09Z</updated>
   
   <summary>一部携帯で画像が表示しない場合は画像のメタデータもチェックしましょう。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="携帯/モバイル" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="37" label="CS5" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="33" label="Illustrator" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="35" label="PhotoShop" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="50" label="モバイル" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="51" label="携帯" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>こんにちは。Nairoです。</p>
<p>CS5が発売されましたね。<br />
使っている方も多いかと思いますが、先日CS5で書き出したファイルが初期設定のままでは、一部携帯端末（例えばSoftbank 905SH）で表示しないということに気づきました。<br />
初期設定ではWeb書き出し機能（Web およびデバイス用に保存）にメタ情報を付与するようになっています。<br />
これです。</p>
<img src="http://yumewaza.yumemi.co.jp/img/postfile/cs5_meta.gif" alt="メタデータ" />
<p>
このまま初期設定で保存してしまうとメタ情報などが付与されてしまい、一部端末で表示しないことがあります。<br />
ということでメタ情報をなしに。<br />
情報を付けなければファイル容量も小さくなりますし忘れずに！<br />
特にインストールした直後などは注意しましょう。<br />
</p>
<p>
メモ書きでした。
</p>]]>
      
   </content>
</entry>
<entry>
   <title>MySQL &quot;SHOW ENGINE INNODB STATUS&quot;の読み方　その1</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/06/mysql_show_engine_innodb_statu.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.391</id>
   
   <published>2010-05-31T16:37:51Z</published>
   <updated>2010-06-01T09:49:52Z</updated>
   
   <summary>kouです。 何か困ったときに便利なのが各種統計情報出力コマンド。弊社では堅く作...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="28" label="innodb" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="29" label="mysql" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[kouです。


何か困ったときに便利なのが各種統計情報出力コマンド。弊社では堅く作るシステムではMySQLを利用することが多く、ストレージエンジンもInnoDBを利用させていただくことが多いです。

というわけで負荷テスト時や運用時に"SHOW ENGINE INNODB STATUS"コマンドをよく使うのですが、各参考サイトを元に自分のメモ代わりに必要そうな項目をまとめてみました。


以下、各セクション毎にポイントをまとめていこうと思います。間違い等があればご指摘いただけるとうれしいです。


出力サンプルのMySQLのバージョンは5.0系です。



<b>ステータスセクション</b>

<pre>
1  mysql> SHOW ENGINE INNODB STATUS\G
2  *************************** 1. row ***************************
3  Status:
4  =====================================
5  100530  9:10:18 INNODB MONITOR OUTPUT
6  =====================================
7  Per second averages calculated from the last 26 seconds
</pre>


7行目の<i>Per second ...</i>は統計のためにデータを取得した時間です。とはいえ、全てのセクションの情報が同時に採取されるわけではないらしいので、この例では以降のセクションのカウンタ値はだいたい26秒間のもの。秒平均値は26秒間の中のどこかの期間内の平均値であることがわかります。






<b>セマフォセクション</b>

<pre>
 8 ----------
 9 SEMAPHORES
10 ----------
11 OS WAIT ARRAY INFO: reservation count 359260, signal count 356251
12 Mutex spin waits 0, rounds 6471518, OS waits 83492
13 RW-shared spins 438760, OS waits 214212; RW-excl spins 34083, OS waits 15339
</pre>




リレーショナルデータベースではそのデータの整合性を担保するために様々な処理でアトミック性を保証しなくてはいけません。MySQLで複数スレッドが動いている中で、クリティカルな処理を行う場合には、そのアトミック性を担保するために同時に１つの操作しかしていないことを保証する仕組み（同期機構）が必要です。LinuxのMySQLでは同期機構にセマフォとMutexを利用しています。



このセクションではそのセマフォ、Mutexに関する統計情報が出力されています。



11行目はスレッドがセマフォの配列に入ったOS待ち（OS wait）の回数です。reservation countが配列に入った回数、signal countが配列に入ってOSからシグナルを受け取った回数です。後述しますが、この回数は少ないほど良いです。



12行目はスレッドのMutex（相互排他ロック）による各種待ち回数を示していて、spin waitsはMutexのスピンロック待ちに入った回数、roundsはスピンロック待ちに入ったロックのスピンラウンド総数を示します。OS waitsはスピンロック待ちでもMutexを取得できなかったため、オペレーティングシステム管理下のセマフォに渡されたロック回数です。



InnoDBはスピンロック待ち→OS待ちの順にロック取得を試みます。スピンロック待ちに入ったロックはinnodb_sync_spin_loopsで設定されたスピンラウンド数（取得待ち回数）を超えるとOS待ちに引き渡されます。OS待ちはスピン待ちに比べて処理コストが大きいので一般的にはOS待ち数が小さい方が好ましいです。OS待ちが多く発生している場合はディスクI/OかInnoDB内部でこれらロックに関する競合が発生している可能性が高いです。OS待ちが毎秒10000以上であればOS待ちを減らす方向でチューニングしましょう。MySQLのスレッド数の変更（innodb_thread_concurrency設定値）が効くと思います。



とはいえ、スピン待ちもCPUリソースを消費するため、あまりspin rounds数が大きいようだとスピン待ちとOS待ちのバランスを取るためにチューニングが必要です(前述のinnodb_sync_spin_loops変数で設定できます。まだ試したことないですが、spin roundが毎秒1000以上であればinnodb_sync_spin_loopsを変更すると良いそうです。もしくはinnodb_thread_concurrency設定値を減らす)。



13行目は読み書きに関する共有ロック(RW-shared)、排他ロック(RW-excl)の各待ち種別カウンタを示していて、それぞれスピン待ち(spins)、OS待ち(OS waits)の回数を示しています。



まとめると、データベースへの並列アクセスが多い場合は同期機構に密接に関わるこのセクションの数字が特に重要で、ほとんどの状況ではOS待ちが多く発生してパフォーマンスが劣化していると思います。その場合はディスクI/OやInnoDB内部の競合が発生している可能性が多いので、MySQLのスレッド数を減らす(innodb_thread_concurrency)と症状が改善されることが多いです。パフォーマンスが出ないからとスレッド数をむやみに増やすと逆に競合が発生しやすくなるため逆効果です。


（もちろん、ボトルネックがどこにあるかによって増やした方がいい場合もありますので、innodb_thread_concurrencyを変更しながらベンチマークをとってチューニングすることが一番望ましいです。）




「その2」へ続く。



参考サイト/書籍：
<a href="http://www.mysqlperformanceblog.com/2006/07/17/show-innodb-status-walk-through/" target="_blank">MySQL Performance Blog - SHOW INNODB STATUS walk through</a>
<a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-monitors.html" target="_blank">MySQL 5.0 Reference Manual - 13.2.13.2. SHOW ENGINE INNODB STATUS and the InnoDB Monitors</a>
<a href="http://www.amazon.co.jp/dp/4873114268/" target="_blank">実践ハイパフォーマンスMySQL 第2版</a>]]>
      
   </content>
</entry>
<entry>
   <title>Autoconf/configureスクリプトを使ってアプリケーションの設定を自動化</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/05/autoconfconfigure.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.390</id>
   
   <published>2010-05-31T10:59:59Z</published>
   <updated>2010-08-02T10:50:02Z</updated>
   
   <summary>GNU の Autoconf ツールの使い方入門をスクリプト言語使用者の視点から解説します。GNU の Autoconf ツールを使うと、サーバーや環境に依存する設定をソースコード中にハードコーディングせずに管理することができます。これは特にバージョン管理システムを使っている場合や、複数環境へのデプロイを行う場合は非常に強力な武器になります。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="58" label="autoconf" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[みなさん、こんにちは、<br />
kaoruです。 <br />
<br />
<h5>はじめに</h5>
UNIX環境でアプリケーションをインストールしたことがある方には、次のコマンドはおなじみだと思います。
<pre>
./configure
make
make install
</pre>
<p>
これらのコマンドは通常はC/C++で書かれたアプリケーションで利用されることが多いのですが、PHPやPythonなど、スクリプト言語で書かれたアプリケーションであっても利用価値があります。
とはいえ、スクリプト言語の開発者にはあまり馴染みがないと思いますので、簡単に紹介をしたいと思います。
</p>

<h5>Autoconf/configureスクリプトを利用するメリット</h5>
<p>
よくある設定ファイルを直接書き換えるような方法だと、書き換えた設定ファイルをバージョン管理システムに登録できないので、困ってしまいます。環境ごとに設定ファイルを複数用意して、全部バージョン管理するような方法だと、一箇所を修正すると全部のファイルを忘れずに修正しないといけなくなります。
</p>
<p>
また、設定ファイルに誤りがあっても、すぐにはわからないという問題があります。configureスクリプトはシェルスクリプトですから、どんな方法のエラーチェックも可能です。
</p>

<h5>configureスクリプトとは</h5>
<p>
configureスクリプトの役割はテンプレートとなるテキストファイルを入力として、文字列置換を行い、出力となるファイルを書き出すことです。よくある入力ファイルはMakefile.inで、出力ファイルはMakefileなのですが、ここでは、config.iniというスクリプト言語用の設定ファイルを出力することを考えてみましょう。
</p>
<h5>テンプレートファイルの書き方</h5>
<p>
出力したいファイルのファイル名の末尾に「.in」をつけたファイル名を用意します。
置き換えたい場所に、＠変数名＠というプレースホルダーの記述をします。ここでいう変数名はシェルの変数名で、configureスクリプトから渡されます。
</p>
<h5>configure.acの書き方</h5>
<p>
こちらは、autoconfのマニュアルを見てほしいのですが、ポイントとしてはAC_SUBSTというマクロを使うことで、先ほどのテンプレートファイルで指定したプレースホルダーの記述を置換することができます。
<p>

<h5>configureスクリプトの生成方法</h5>
シェルのプロンプトから
<pre>autoreconf</pre>
と入力するだけで、configure.acからconfigureスクリプトが生成されます。

<h5>configureスクリプトの使い方</h5>
<p>./configure --help とすると、おなじみのヘルプが表示されます。</p>

<h5>サンプル</h5>
<b>config/config.ini.in</b><br />
<pre>
BASE_DIR = @abs_srcdir@
MASTER_DB = @MASTER_DB@
SLAVE_DB = @SLAVE_DB@
IMAGE_DIR = @IMAGE_DIR@
</pre>
<br />
<b>configure.ac</b><br />
<pre>
AC_PREREQ(2.59)
AC_INIT(MyProject, 1.00)

AC_CONFIG_SRCDIR([config/config.ini.in])

AC_ARG_ENABLE(
    [image-dir],
    AS_HELP_STRING([--enable-image-dir=ARG], [画像ファイルの置き場所]),
    [IMAGE_DIR=$enableval],
    [IMAGE_DIR=$prefix/htdocs/image]
)
AC_SUBST(IMAGE_DIR)

AC_ARG_ENABLE(
    [master-db],
    AS_HELP_STRING([--enable-master-db=ARG], [マスターDBのDSN]),
    [MASTER_DB=$enableval],
    [MASTER_DB=]
)
AC_SUBST(MASTER_DB)

AC_ARG_ENABLE(
    [slave-db],
    AS_HELP_STRING([--enable-slave-db=ARG], [スレイブDBのDSN]),
    [SLAVE_DB=$enableval],
    [SLAVE_DB=]
)
AC_SUBST(SLAVE_DB)

AC_CONFIG_FILES([config/config.ini])
AC_OUTPUT
</pre>

<h5>サンプルの実行例</h5>
<code>
autoreconf<br />
./configure --enable-image-dir=/home/test/image --enable-master-db="mysql:host=master-db01.sample port=3306 user=web_user" --enable-slave-db="mysql:slave-db01.sample port=3306 user=web_user"
</code>
<p>
次のようなメッセージが表示されます。
</p>
<pre>
configure: creating ./config.status
config.status: creating config/config.ini
</pre>
<p>
config/config.ini が生成されているはずなので、確認してみてください。
</p>]]>
      
   </content>
</entry>
<entry>
   <title>TokyoTyrantとMySQLはSSDによって性能が上がるのか？</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/04/tokyotyrantmysqlssd.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.372</id>
   
   <published>2010-04-23T09:10:12Z</published>
   <updated>2010-04-26T01:11:25Z</updated>
   
   <summary>  お久しぶりです。kouです。     先日、社内勉強会を実施しました！   ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="勉強会" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[ 

お久しぶりです。kouです。
 
 
先日、社内勉強会を実施しました！
 

今回は「Tokyo TyrantとMySQLはSSDによって性能があがるのか？」をテーマにちきんさんが社内講師を務めました。現在、ゆめみではソーシャルアプリ開発を進めていて、そこで利用するTTやSSDの技術検証を行った結果をみんなで共有です。
 
 
勉強会の詳細はスライドをご覧ください。

 
<div style="width:425px" id="__ss_3825748"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/yumemikouda/ssdtokyotyrantmysql" title="SSDとTokyoTyrantやMySQLの性能検証">SSDとTokyoTyrantやMySQLの性能検証</a></strong><object width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=306tokyotyrant-100422233509-phpapp01&stripped_title=ssdtokyotyrantmysql" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=306tokyotyrant-100422233509-phpapp01&stripped_title=ssdtokyotyrantmysql" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/yumemikouda">yumemikouda</a>.</div></div>
 

 
以下、勉強会の様子。

 
<img alt="study_201004_01.jpg" src="http://yumewaza.yumemi.co.jp/img/postfile/study_201004_01.jpg" width="320" height="240" />



<img alt="study_201004_02.jpg" src="http://yumewaza.yumemi.co.jp/img/postfile/study_201004_02.jpg" width="320" height="240" />



 


次回はUstreamで中継してみたいです。
 
 ]]>
      
   </content>
</entry>
<entry>
   <title>C++/Boostとコルーチンを使って非同期I/Oを実現（C10K問題もこれで解決？）</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/04/cboostioc10k.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.367</id>
   
   <published>2010-04-19T07:00:07Z</published>
   <updated>2010-04-19T07:20:15Z</updated>
   
   <summary>みなさん、こんにちは、 kaoruです。  今回は、C10K問題 (参考１, 参...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>みなさん、こんにちは、<br />
kaoruです。 <br />
<br />
今回は、C10K問題 (<a href="http://www.atmarkit.co.jp/news/analysis/200701/09/c10k.html" target="_target">参考１</a>, <a href="http://tinyurl.com/hbmbh" target="_blank">参考２</a>) を回避するために<a href="http://tinyurl.com/4dgvsd" target="_blank">コルーチン</a>を使う方法をご紹介したいと思います。<br />
<br />
また、ちょっと実用的な例として、言語としてC++、ライブラリーとして<a href="http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio.html" target="_blank">Boost.Asio</a>とBoost.Asio付属のコルーチンを利用して、
ApacheBenchもどきを実際に作ってみました。<br />
<br />
ネットワークプログラミングを調査しようと思ったきっかけは、
技術評論社から出ている<a href="http://tinyurl.com/yywzubz" target="_blank">「WEB+DB PRESS Vol.55」</a>の
「モダンネットワークプログラミング入門」という記事です。
こちらには、ネットワークプログラミングの基本的な設計モデルが分かりやすく説明されているため、とても参考になります。<br />
<br />
ご存じのように、C10K問題とは、ハードウェアに余裕があるにもかかわらず、同時コネクション数が１万前後になると、パフォーマンスが急速に劣化するという問題です。
これは、ネットワークアプリケーションの伝統的な設計ではコネクション数に比例する数のプロセスやスレッドが生成されることに原因があります。
例として、Apache HTTP Serverのpreforkモードでは、コネクション数に比例する数の子プロセスが起動して、リクエストを処理します。
同時コネクション数が１万前後にするには、子プロセスを１万前後起動しなければならず、これはあまり現実的な数字ではありません。<br />
<br />
C10K問題を回避するためには、コネクション数とプロセス数やスレッド数が比例しないような設計をしなければなりません。<br />
これには、非同期I/Oを利用したイベント駆動モデルが有効です。
これはすなわち、接続成功、ヘッダーの読み取り完了、レスポンスの送出完了などといったイベントの発生毎にあらかじめ登録しておいたイベントハンドラを呼び出してもらう方法です。
この方法は非常に効率がよいのですが、本来はひと続きの処理がたくさんのイベントハンドラの中にばらばらになって散らばってしまうため、
処理の流れが分かりにくくソースコードの可読性が悪いという欠点がありました。
</p>

<p>コルーチンと呼ばれる手法を使うと、非同期I/Oを利用したイベント駆動モデルでありながら、同期モデルとほぼ同じようにプログラミングを行うことができ、
処理の流れが非常に分かりやすくなります。<br />
コルーチンとは、プログラムの流れの中で中断・再開ができたり、スレッドのように制御を分岐したりできるプログラミングのしくみです。Luaなどの一部の言語では言語レベルでサポートされていますが、C/C++ではライブラリーを使って実装します。<br />
<br />
</p>

<p>今回作ったソースコードの一部を掲載します。 (この記事の下のリンクから全てのソースコードをダウンロードできます。)</p>

<PRE><FONT COLOR="#000099">
#include "yield.hpp" // Enable the pseudo-keywords reenter, yield and fork.
</FONT><FONT COLOR="#FF6633">
void</FONT> client<B><FONT COLOR="#663300">::</FONT></B><FONT COLOR="#990000">operator</FONT><B><FONT COLOR="#663300">()(</FONT></B>

        boost<B><FONT COLOR="#663300">::</FONT></B>system<B><FONT COLOR="#663300">::</FONT></B>error_code ec<B><FONT COLOR="#663300">,</FONT></B>
        std<B><FONT COLOR="#663300">::</FONT></B>size_t length<B><FONT COLOR="#663300">,</FONT></B>
        tcp<B><FONT COLOR="#663300">::</FONT></B>resolver<B><FONT COLOR="#663300">::</FONT></B>iterator endpoint_iterator<B><FONT COLOR="#663300">)
{</FONT></B><FONT COLOR="#990000">

    static</FONT><FONT COLOR="#FF6633"> int</FONT> n<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000">
    static</FONT><FONT COLOR="#FF6633"> int</FONT> c<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#FF0000">

    if</FONT><B><FONT COLOR="#663300"> (</FONT></B>ec<B><FONT COLOR="#663300"> &amp;&amp;</FONT></B> ec<B><FONT COLOR="#663300"> !=</FONT></B> boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>error<B><FONT COLOR="#663300">::</FONT></B>eof<B><FONT COLOR="#663300">) {</FONT></B>

        std<B><FONT COLOR="#663300">::</FONT></B>cerr<B><FONT COLOR="#663300"> &lt;&lt;</FONT></B> ec<B><FONT COLOR="#663300">.</FONT></B>message<B><FONT COLOR="#663300">() &lt;&lt;</FONT></B> std<B><FONT COLOR="#663300">::</FONT></B>endl<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#FF0000">
        return</FONT><B><FONT COLOR="#663300">;
    }</FONT></B><I><FONT COLOR="#999999">

    // On reentering a coroutine, control jumps to the location of the last
    // yield or fork. The argument to the "reenter" pseudo-keyword can be a
    // pointer or reference to an object of type coroutine.
</FONT></I>    reenter<B><FONT COLOR="#663300"> (</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">)
    {</FONT></B><FONT COLOR="#FF0000">
        for</FONT><B><FONT COLOR="#663300"> (</FONT></B>c<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">;</FONT></B> c<B><FONT COLOR="#663300"> &lt;</FONT></B> concurrency_level_<B><FONT COLOR="#663300"> &amp;&amp;</FONT></B> c<B><FONT COLOR="#663300"> &lt;</FONT></B> num_request_<B><FONT COLOR="#663300">; ++</FONT></B>c<B><FONT COLOR="#663300">) {</FONT></B>

            fork client<B><FONT COLOR="#663300">(*</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">)();</FONT></B><FONT COLOR="#FF0000">

            if</FONT><B><FONT COLOR="#663300"> (</FONT></B>is_child<B><FONT COLOR="#663300">())</FONT></B><FONT COLOR="#FF0000">
                break</FONT><B><FONT COLOR="#663300">;
        }</FONT></B><FONT COLOR="#FF0000">

        if</FONT><B><FONT COLOR="#663300"> (</FONT></B>is_parent<B><FONT COLOR="#663300">())</FONT></B><FONT COLOR="#FF0000">
            return</FONT><B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#FF0000">

        while</FONT><B><FONT COLOR="#663300"> (</FONT></B>n<B><FONT COLOR="#663300"> &lt;</FONT></B> num_request_<B><FONT COLOR="#663300">) {</FONT></B>

            socket_<B><FONT COLOR="#663300">.</FONT></B>reset<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#990000">new</FONT> boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>ip<B><FONT COLOR="#663300">::</FONT></B>tcp<B><FONT COLOR="#663300">::</FONT></B>socket<B><FONT COLOR="#663300">(</FONT></B>io_service_<B><FONT COLOR="#663300">));</FONT></B>

            yield socket_<B><FONT COLOR="#663300">-&gt;</FONT></B>async_connect<B><FONT COLOR="#663300">(</FONT></B>endpoint_<B><FONT COLOR="#663300">, *</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">);</FONT></B>

            n<B><FONT COLOR="#663300">++;</FONT></B><FONT COLOR="#FF0000">
            if</FONT><B><FONT COLOR="#663300"> (</FONT></B>n<B><FONT COLOR="#663300"> %</FONT></B><FONT COLOR="#999900"> 1000</FONT><B><FONT COLOR="#663300"> ==</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">)</FONT></B>

                cout<B><FONT COLOR="#663300"> &lt;&lt;</FONT></B><FONT COLOR="#009900"> "Completed "</FONT><B><FONT COLOR="#663300"> &lt;&lt;</FONT></B> n<B><FONT COLOR="#663300"> &lt;&lt;</FONT></B><FONT COLOR="#009900"> " requests"</FONT><B><FONT COLOR="#663300"> &lt;&lt;</FONT></B> endl<B><FONT COLOR="#663300">;</FONT></B><I><FONT COLOR="#999999">

            // Send the request.
</FONT></I>            yield boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>async_write<B><FONT COLOR="#663300">(
                *</FONT></B>socket_<B><FONT COLOR="#663300">,</FONT></B>
                boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>buffer<B><FONT COLOR="#663300">(</FONT></B>

                    request_<B><FONT COLOR="#663300">.</FONT></B>c_str<B><FONT COLOR="#663300">(),</FONT></B>
                    request_<B><FONT COLOR="#663300">.</FONT></B>size<B><FONT COLOR="#663300">()
                ),
                *</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">
            );</FONT></B><I><FONT COLOR="#999999">

            // Start reading remaining data until EOF.
</FONT></I><FONT COLOR="#990000">            static</FONT><FONT COLOR="#FF6633"> char</FONT> dummy_buffer<B><FONT COLOR="#663300">[</FONT></B><FONT COLOR="#999900">1</FONT><B><FONT COLOR="#663300"> *</FONT></B><FONT COLOR="#999900"> 1024</FONT><B><FONT COLOR="#663300"> *</FONT></B><FONT COLOR="#999900"> 1024</FONT><B><FONT COLOR="#663300">];</FONT></B><I><FONT COLOR="#999999"> // Dirty buffer.

</FONT></I>            yield boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>async_read<B><FONT COLOR="#663300">(
                *</FONT></B>socket_<B><FONT COLOR="#663300">,</FONT></B>
                boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>buffer<B><FONT COLOR="#663300">(</FONT></B>dummy_buffer<B><FONT COLOR="#663300">,</FONT></B><FONT COLOR="#990000"> sizeof</FONT><B><FONT COLOR="#663300">(</FONT></B>dummy_buffer<B><FONT COLOR="#663300">)),</FONT></B>

                boost<B><FONT COLOR="#663300">::</FONT></B>asio<B><FONT COLOR="#663300">::</FONT></B>transfer_all<B><FONT COLOR="#663300">(),
                *</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">);</FONT></B><I><FONT COLOR="#999999">

            // Initiate graceful connection closure.
</FONT></I>            socket_<B><FONT COLOR="#663300">-&gt;</FONT></B>shutdown<B><FONT COLOR="#663300">(</FONT></B>tcp<B><FONT COLOR="#663300">::</FONT></B>socket<B><FONT COLOR="#663300">::</FONT></B>shutdown_both<B><FONT COLOR="#663300">,</FONT></B> ec<B><FONT COLOR="#663300">);
        }
    }</FONT></B>
<B><FONT COLOR="#663300">}</FONT></B><FONT COLOR="#000099">

#include "unyield.hpp" // Disable the pseudo-keywords reenter, yield and fork.
</FONT></PRE>

<p>#include "yield.hpp" から #include "unyield.hpp" の区間では、
reenter, yield, fork という３種類のキーワードが有効になります。<br />
（実際にはプリプロセッサーマクロですが、キーワードであるかのように使えます。）<br />
</p>

<p>コルーチン化したいコードの部分をreenter { } で囲み、
async_connect, async_read, async_write といった非同期I/Oを行う関数の手前に、
yieldキーワードをつけます。(下図の(1),(2))<br />
forkキーワードは、UNIXのforkシステムコールと同じような感じに、コルーチンオブジェクトをコピーして子供のコルーチンを生成します。(下図の親・子)
is_child(), is_parent()という関数で、子として実行しているのか、親として実行しているのかがわかりますので、
処理を分岐することが可能です。forkキーワードを使っても、実際にはプロセスやスレッドは生成されませんので、非常に軽量です。<br />
</p>

<p>yieldキーワードを使うと、非同期I/Oが完了したときに次の行から処理が再開されます。すなわち、下図で説明すると、まず最初に(1)から(2)まで処理が進み、ここでyieldキーワードがありますので、async_connect関数（非同期接続を行う関数です。）が実行された後、一旦reenterブロックを抜けます。抜ける際に、再開する場所として(2)の場所が自動的に保存されます。(2)のasync_connectの引数として*thisが渡されていますので、接続完了時にもう一度(1)に制御が来ます。ここで、先ほど(2)まで処理が進んだことを保存していましたから、(1)から(2)に制御が移動し、(2)から処理が再開されるという仕組みです。<br />
</p>

<img alt="co-routine.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/co-routine.gif" width="500" height="313" />

<p>以前はこのような処理を記述する際には、あらかじめ同時接続数と同じ数のスレッドを生成した後、
同期処理を行うAPIを用いて記述することが多かったのですが、今回はスレッドは明示的に生成することなく実装ができました。<br />
</p>

<p>この例のように、まるで同期処理を書いているかのような感覚でプログラミングを行うことができるのがうれしいところです。<br />
</p>

<p>前回の記事「<a href="http://yumewaza.yumemi.co.jp/2010/04/_ka.html">WEBサーバーを比較してみる</a>」と同じ環境で、nginxサーバーに対してリクエストを発行したところ、
ApacheBench を若干上回る 9345.84 req/s という結果を得ました。<br />
</p>

<p>また、機能が違うため正しい比較はできませんが、同時コネクション数を10000程度まで増やしても、<br />
ApacheBenchよりもメモリー使用量が少なくなりました。<br />
</p>

<p>今回、コルーチンを使うことで、ApacheBenchもどきのクライアントを非常に簡単に作ることができました。<br />
みなさんが、非同期I/Oを使ったプログラミングをされる際に、少しでも参考になるところがありましたら幸いでございます。<br />
</p>

<p>
<b>今回作成したソースコード</b><br />
<a href="http://yumewaza.yumemi.co.jp/img/postfile/http_stress_tool-0.10.zip">ファイルをダウンロード</a><br />
<br />
<b>ビルド方法</b><br />
※ビルドには、あらかじめ<a href="http://www.boost.org/" target="_blank">Boost C++ Libraries</a>をインストールして、適切にパスの設定をする必要があります。<br />
<br />
<b>Windows環境の場合</b><br />
Visual Studio 2008 で、http_stress_tool.slnを開いてください。<br />
<br />
<b>UNIX環境の場合</b><br />
Makefile等は用意していません。以下のようなコマンドでビルドができます。<br />
g++ -O3 -o http_stress_tool http_client.cpp main.cpp -Wall -Wextra -lboost_system -lboost_date_time<br />
<br />
<br />
</p>]]>
      
   </content>
</entry>
<entry>
   <title>WEBサーバーを比較してみる</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/04/_ka.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.354</id>
   
   <published>2010-04-01T08:25:45Z</published>
   <updated>2010-04-01T08:30:34Z</updated>
   
   <summary>WEBサーバーを比較してみる</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>
はじめまして、kaoruです。
</p>
<p>
ゆめみでは伝統的にWEBサービスを提供するにあたって、<a href="http://httpd.apache.org/">Apache HTTP Server</a>+<a href="http://www.php.net/">PHP</a>というミドルウェア構成を利用してきました。
</p>
<p>
近年では単純な閲覧型のWEBサイトを越えて、SNSやコミュニティーサービスなど、ユーザーが自らリアルタイムに参加できるようなWEBサービスが一般的になってきています。このようなWEBサービスを提供するためには、膨大なトラフィックをリアルタイムに処理できるようなシステム構成が求められています。
</p>
<p>
&nbsp;このような背景もあり、今回は今までよく使っていたApache HTTP Serverと最近よく目にするようになってきた<a href="http://nginx.org/">nginx</a>というWEBサーバーの基本的な性能を比較してみましたのでご紹介してみたいと思います。
</p>
<p>なお、今回の性能の計測は簡易的なものであり、参考程度のものであることはご了承ください。
</p>
<p>
<img alt="20100331.WEB-server-compara.gif" src="http://yumewaza.yumemi.co.jp/img/postfile/20100331_WEB-server-compara.gif" width="498" height="505" />
</p>
<p>
グラフの縦軸は１秒間あたりに処理したリクエスト数の平均、横軸は同時接続数で、localhostから<a href="http://httpd.apache.org/docs/2.2/programs/ab.html">ApacheBench</a>を使って計測しました。上の３つはApache HTTP Serverで、configure時に指定する<a href="http://httpd.apache.org/docs/2.2/mpm.html">MPMオプション</a>を、prefork, worker, eventと変えたものです。nginxは最近よく聞くようになったWEBサーバーです。<a href="http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio.html">Boost.Asio</a>はC++のライブラリーで、非同期のネットワーク処理ができます。ライブラリーに付属しているサンプルプログラムを試してみました。
</p>
<p>
結果を見ると、Apache HTTP Serverよりもnginxはコネクション数にかかわらず性能が高いことが分かります。また、グラフからはわかりませんが、アーキテクチャーの違いからか、nginxの方がリソースの消費量が大幅に少なくなっているようです。Boost.Asioはライブラリーなので他のアプリケーションと単純な比較はできませんが、アプリケーションを実装するプラットフォームとしてはかなり高性能であると言えます。
</p>
<p>
今回は、手始めとして、固定の簡単なテキストファイルを取得する試験を行いました。動的にコンテンツを返さなければいけないかどうかや、使いたい機能によってもかわってきますが、nginxで必要なことができるなら、とても魅力的な選択肢になると思います。
</p>
<p>
今回の試験に用いたサーバーのスペックとアプリケーションのバージョンを挙げておきます。
</p>
<pre>
Intel(R) Xeon(R) 2.33GHz (64bit, ８コア）
Linux 2.6.18 x86_64
Mem:   1048576k total

httpd-2.2.14
nginx-0.8.34
boost_1_42_0
</pre>]]>
      
   </content>
</entry>
<entry>
   <title>[mod_ktai] FAQ その1</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/02/mod_ktai_faq_1.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.344</id>
   
   <published>2010-02-24T02:05:34Z</published>
   <updated>2010-02-24T02:13:05Z</updated>
   
   <summary>「mod_ktai」は、ゆめみが開発したApacheモジュールです。mod_ktaiの利用法に関してのご質問についてここにまとめていければと思います。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="mod_ktai" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="mod_ktai" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[こんにちは、kouです。 



日頃、mod_ktaiをご利用いただきありがとうございます！


mod_ktaiの利用法に関してご質問をいただくことがあるのですが、全てのご質問にお答えできておらず大変申し訳なく思っています。今後は<a href="http://labs.yumemi.co.jp/labs/mod/man_contents.html" target="_blank">mod_ktai</a>に関していただいたご質問についてここにまとめていければと思ってますので、ご参考になれば幸いです。


<b>Q. Apacheを起動しようとしたところ下記のようなエラーが発生します。</b>


<pre>
Cannot load /etc/httpd/modules/mod_ktai_image.so into server: 
/etc/httpd/modules/mod_ktai_image.so: 
undefined symbol: _ZN7libktai4info8constant29X_KTAI_INFO_EXT_SCREEN_HEIGHTE
</pre>


<b>A. モジュールの読み込み順に原因があります。</b>

mod_ktaiシリーズはmod_ktai_infoが存在することを前提とした各モジュールの作りになっています。とくにmod_ktai_imageはmod_ktai_infoへの依存度が高いためmod_ktai_imageがApacheに読み込まれる前にmod_ktai_infoが読み込まれていないと上記のようなエラーが発生してしまいます。必ず

<ol>
<li>mod_ktai_info</li>
<li>mod_ktai_image</li>
</ol>

の順に読み込まれるようにLoadModuleの定義をしてください。


<b>Includeを利用して外部ファイルから定義を読み込んでいる場合</b>

<pre>
Include conf.d/ktai_info.conf
Include conf.d/ktai_image.conf
</pre>

<b>httpd.confにLoadModuleを直接記述している場合</b>

<pre>
LoadModule ktai_info_module modules/mod_ktai_info.so
LoadModule ktai_image_module modules/mod_ktai_image.so
</pre>
]]>
      
   </content>
</entry>
<entry>
   <title>【3キャリア共通コーディング】au（EZweb）端末で、divの隙間を消す裏技。</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/02/1temp_ezwebdiv.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.337</id>
   
   <published>2010-02-15T06:00:00Z</published>
   <updated>2010-06-08T11:24:53Z</updated>
   
   <summary>お久しぶりです。Shoe&apos;sです。 モバイル向けのXHTMLで3キャリアで同じ表...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="携帯/モバイル" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[お久しぶりです。Shoe'sです。<br />
<br />
モバイル向けのXHTMLで3キャリアで同じ表現をしようとした場合には、必然的に一番表現能力の劣るドコモに合わせる必要があります。<a href="http://www.amazon.co.jp/exec/obidos/ASIN/4844326317/yumemicojp-22/ref=nosim" target="_blank">モバイルユーザビリティ・デザイン</a>にも載せているコーディング例の他にも、ハマってしまうポイントや汎用的に表現したいもの。という観点から今回は『au（EZweb）端末で、div要素間の無駄な隙間（スペース）を生まない』方法を紹介します。<br />
<br />

モバイルに於ける細かい制約等はここでは控えますが、「div要素で隙間が生まれる」ということは、3キャリア共通では「margin属性やpadding属性に対応していない」ということが前提になります。というところで、まずは問題点から。<br />
<br />
<h3 style="color:#009900">au（EZweb）端末に於ける、div要素の問題点</h3>
ごく普通にdiv要素を記述すると、au（EZweb）端末では要素の上下に余分なスペースが開いてしまいます。<br />
<img alt="3キャリア共通コーディング：au（EZweb）端末に於けるdiv要素の問題点" src="http://yumewaza.yumemi.co.jp/img/postfile/ezwebdiv_1.png" width="224" height="120" style="margin:8px" /><br />
モバイルサイトでより凝ったレイアウトを実現しようとした場合に、悩んだことがある方は多いと思います。<br />
<br />
<h3 style="color:#009900">div要素を入れ子で記述してみる</h3>
解決策として、真っ先に思い浮かぶ手法だと思いますが、以下の様にdiv要素-Bのスペースによって、外側（div要素-Bの下）に数ピクセルの予期しないdiv要素-Aの背景色が表示されてしまいます。<br />
<img alt="3キャリア共通コーディング：div要素を入れ子に記述しau（EZweb）端末で表示" src="http://yumewaza.yumemi.co.jp/img/postfile/ezwebdiv_2.png" width="224" height="120" style="margin:8px" /><br />
この方法で落ち着いてるモバイルサイトはよく見掛けます。<br/>
ただし、このままではdiv要素を繋ぐ画像を表示させたい場合に、しっくりこないのです。<br />
<img alt="3キャリア共通コーディング：div要素を入れ子に記述しau（EZweb）端末で表示" src="http://yumewaza.yumemi.co.jp/img/postfile/ezwebdiv_3.png" width="224" height="120" style="margin:8px" />　　<img alt="3キャリア共通コーディング：div要素を入れ子に記述しau（EZweb）端末で表示" src="http://yumewaza.yumemi.co.jp/img/postfile/ezwebdiv_4.png" width="224" height="120" style="margin:8px" /><br />
div要素-Aの下辺（左）に置いても、div要素-Bの上辺（右）に置いても、<br />
表示させている側の背景色が数ピクセル、余計なスペースとなって立ちはだかります。<br />
<br />
<h3 style="color:#009900">目から鱗のコーディングで解決する</h3>
このような問題は、細かな説明は省きますが（といっても説明のしようがありませんが）、<br />
『全て入れ子にし、閉じタグを最後にまとめる』というコーディングにより解決できるのです！<br />
<br />
是非、活用してみてください。<br />
<br /><br />
<h3 style="color:#0000cc">■3キャリアでdiv要素間の無駄な隙間（スペース）を生まないソース</h3>
<pre>
<span style="color:#990000">&lt;div style="background-color:char"&gt;</span>div要素-A&lt;br /&gt;
	<span style="color:#000099">&lt;div style="background-color:char"&gt;</span>div要素-B&lt;br /&gt;
		<span style="color:#009900">&lt;div style="background-color:char"&gt;</span>div要素-C&lt;br /&gt;
		<span style="color:#009900">&lt;/div&gt;</span>
	<span style="color:#000099">&lt;/div&gt;</span>
<span style="color:#990000">&lt;/div&gt;</span>
</pre>
<br />]]>
      
   </content>
</entry>
<entry>
   <title>mixiアプリの開発環境</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/02/mixi.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.332</id>
   
   <published>2010-02-03T08:47:14Z</published>
   <updated>2010-02-03T14:37:13Z</updated>
   
   <summary> こんにちは、kouです。 最近、mixiアプリモバイルの開発をいくつか進めてい...</summary>
   <author>
      <name></name>
      
   </author>
   
   <category term="26" label="mixiアプリ" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[

こんにちは、kouです。


最近、<a href="http://developer.mixi.co.jp/appli" target="_blank">mixiアプリモバイル</a>の開発をいくつか進めていますが、mixiアプリモバイルは携帯端末とソーシャルアプリケーションプロバイダ（弊社のようなmixiアプリを開発しようとしているところ）の間にmixiサーバが入るため、開発効率が思ったほどあがらず困っていました。



mixiアプリモバイルではサーバ間通信が前提のため、開発環境のみで動作確認ができないことが開発効率を下げる原因の一つになっていました。mixiアプリプラットフォームにも開発で簡単に使えるsandboxのようなところがないため、ソーシャルグラフに実データを使わざるを得ず、テストデータの用意が面倒ですし、弊社の携帯サイト開発で使っている自社製携帯端末エミュレーターもひと工夫しないと使えないということで、通常の携帯サイト開発に比べていくつか乗り越えないといけない壁があります。


<img alt="sap1.jpg" src="http://yumewaza.yumemi.co.jp/img/postfile/sap1.jpg" width="491" height="161" />



そこでApache incubatorで開発が進められているOpenSocialコンテナ「<a href="http://incubator.apache.org/shindig/" target="_blank">Shindig</a>」とShindigに対応したSNS「<a href="http://code.google.com/p/partuza/" target="_blank">partuza</a>」を組み合わせたmixiアプリプラットフォームシミュレータを用意することにしました。mixiアプリはOpenSocial準拠ですが、独自機能が拡張されていますので、partuzaもそれにあわせて拡張して使ってます。その結果、弊社では下記のような開発環境を用意しています。



<img alt="sap2.jpg" src="http://yumewaza.yumemi.co.jp/img/postfile/sap2.gif" width="555" height="264" />




弊社ではモバイル開発がメインなのでpartuzaも携帯対応しています。



これで開発効率が上がればモバゲー、GREEなどの各OpenSocialプラットフォームエミュレーターも作っていきたいです。


]]>
      
   </content>
</entry>
<entry>
   <title>Android端末Xperia タッチ＆トライ（起動時間の動画有り）</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/01/androidxperia.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.326</id>
   
   <published>2010-01-22T01:07:14Z</published>
   <updated>2010-02-24T02:13:48Z</updated>
   
   <summary>Android端末Xperiaの起動時間を測定してみました。圧倒的に早いです。</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Android" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="22" label="android" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>大変ご無沙汰しております。久富です。2010年春にdocomoから出るAndroid端末である<strong>Xperia</strong>の製品発表会があったので、参加してきました。残念ながら途中からの参加でしたので、いきなり実機レポートから入りたいと思います。ケータイで撮影しているため、影が出ている写真で申し訳ありません。</p>
<p><img src="http://yumewaza.yumemi.co.jp/img/postfile/xperia_devphone_iphone.jpg" width="500" height="342"  alt="左からXperia、Android Dev Phone、iPhone"/><br />まずは外観参照。<strong>Android Dev Phone</strong>と<strong>Xperia</strong>、そして<strong>iPhone</strong>と並べてみました。画面の大きさに注目してください。Xperiaの画面は大きくてきれいですが、この写真で見るほど「でか！」という印象は実機ではありません。使いやすくよくまとまっており、手持ちした感じもしっくりなじみます。ソニーが近未来の電話を作ったらこうなる、そんな質感のパッケージングでした。</p>
<p><img src="http://yumewaza.yumemi.co.jp/img/postfile/xperia_watch.jpg" width="500" height="504"  alt="XperiaとAndroid Dev Phoneのウィジェット時計表示の比較"/><br />つぎにウィジェットを追加してみようと思ったのですが、このあたりで期待していたものと違うことに気付きます。「Android標準インターフェースとあんまり変わってない……。」私の思い込みかもしれませんが、<strong>Xperia</strong>はかなりUIにこだわった端末である、との触れ込みだったような記憶があります。実際は、確かに変わっているUIもありますが、もとのままのUIもあります。この写真を見ていただいてもわかるとおり、ウィジェットの時計のデザインは変わってますが、Android Marketのアイコンは両者とも同じです。この二台とも、Android 1.6が入っています。</p>
<p><img src="http://yumewaza.yumemi.co.jp/img/postfile/xperia_dialer.jpg" width="500" height="463"  alt="XperiaとAndroid Dev Phoneのダイヤル画面の比較"/><br />次に電話をかけています。ここでXperia独特の部分に気付きます。「電話をかける」ボタンと「電話を切る」ボタンが、ハードウェアボタンでなくソフトウェアボタンになっています。Android Dev Phoneはハードウェアボタンの「電話を切る」ボタンで画面ロックがかかり液晶の電源が切れるようになっているので、それに慣れているとちょっと戸惑いますね。</p>
<p><img src="http://yumewaza.yumemi.co.jp/img/postfile/xperia_apps.jpg" width="500" height="489"  alt="XperiaとAndroid Dev Phoneのアプリ一覧"/><br />これはアプリ一覧を表示したところです。Xperiaはアイコンが縦５列並びます。でも、他のアイコンは今までと似たり寄ったりなので戸惑うことなく操作できます。アプリ一覧を出す操作も、Notificationを呼び出す操作も、Android Dev Phoneと全く同じです。</p>
<p><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/xubqBje9hgk&hl=ja_JP&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/xubqBje9hgk&hl=ja_JP&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br />次に、<strong>起動時間</strong>を測定してみました。圧倒的に<strong>速い</strong>です。でも、使用感はそれほど変わりません。重いアプリとか動かしたら違うのかもしれませんね。</p>
<p><strong>Xperia</strong>には他にもMediascape、Timescapeというアプリが搭載されておりますが、今回はAndroid端末としてどうだろう？という観点からいろいろと触ってみました。そして思ったことは「普通のAndroid端末じゃん」ってことです。ハードウェア・ソフトウェア両方のボタンデザインなど確かに洗練されていますが、基本的な使い方は他の端末と変わることがないですね。アプリ開発者の視点からすると、画面のピクセル数が多いことは考慮したほうがいい感じです。特にゲームなど作られる場合は、<strong>Xperia</strong>と他の端末とで動作確認したほうが確実かと思いました。それではまた！</p>]]>
      
   </content>
</entry>
<entry>
   <title>実践している読書術（３）</title>
   <link rel="alternate" type="text/html" href="http://yumewaza.yumemi.co.jp/2010/01/reading_03.html" />
   <id>tag:yumewaza.yumemi.co.jp,2010://5.313</id>
   
   <published>2010-01-13T06:02:14Z</published>
   <updated>2010-01-13T06:03:12Z</updated>
   
   <summary>どのようなタイミングで読んでいるか・そのための準備</summary>
   <author>
      <name></name>
      
   </author>
   
   <category term="20" label="速読" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="21" label="読書術" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://yumewaza.yumemi.co.jp/">
      <![CDATA[<p>こんにちは、深田です。</p>
<p>読書術のご紹介も第3回となりました。思ったより続きそうですが、読んで面白い内容になってるんだろうか？？（<a href="http://yumewaza.yumemi.co.jp/2009/09/reading_02.html">第二回はこちら</a>）</p>
<p>今回は</p>
<ol>
	<li>本をどのように買うか・選ぶか</li>
	<li>どのようなタイミングで読んでいるか・そのための準備をどうしているか</li>
	<li>1冊の本を読む際の読み方をどうしているか<br />
		読む準備をどのようにしているか<br />
		中身をどういうパートに分割しているか<br />
		中身の各パートをどういう順序で読むか<br />
		それぞれのパートをどういう読み方をしているか</li>
	<li>読んだ後どのようにしているか</li>
</ol>
<p>の<br />
2.どのようなタイミングで読んでいるか・そのための準備をどうしているかに入ります。</p>]]>
      <![CDATA[<h2>どのようなタイミングで読んでいるか・そのための準備</h2>
<p>大体なのですが、私の読書時間はおそらく月間15から20時間程度と思います。自分の読書のタイミングを振り返ってみて思うのは、30分以上のまとまった時間を読書に充てていることはほとんどないということです。基本的にはすきま時間の積み重ねで本を読んでいます。思いつくままにいつどこで読んでいるかを列挙してみると・・・</p>
<p>・駅での電車待ち<br />
	・電車の中<br />
	・一人での食事中<br />
	・待ち合わせの待ち時間<br />
	・トイレの中<br />
	・エレベーター昇降時<br />
	・PCの立ち上げ待ち</p>
<p>というところです。我ながら細切れですね＾＾；<br />
	一番長いのは電車の中です。通勤電車、行き帰りで合わせると30分以上は読書に充てられます。アポがある場合はその移動中にも読みますのでここは結構大きい気がします。</p>
<p>こういうすきま時間で読むことが多いために自然にそうなっていますが、大体鞄の中には常に2冊の本が入っています。<br />
1冊はハードカバー型の少しサイズの大きな本（概ねビジネス関連の書籍です）、1冊は文庫型のサイズの小さな本（歴史系の本が多いです）。日中はハードカバー型の本を主に読みます。私の鞄はスーツケースタイプなので平置きにしないと開け閉めがしづらいので、電車に乗る際にはあらかじめ本だけ出しておいて脇に抱えて駅に向かいます。ホームに着くと早速読書を開始します。そのまま電車の中でも読み続けます。</p>
<p>なぜ2冊入れているかといいますと、疲れていたりお酒を飲んでいたりする場合にはビジネス関連の書籍を読むのはしんどいためです。頭がしっかり回転していないとき・リラックスしたいときには趣味に近い文庫型の歴史小説系の本など頭に入りやすい本を読むことにしています。また、いずれかの読み終わりが近くなると3冊持ち歩くこともよくあります。</p>
<p>またこれは私の性格かもしれませんが、複数の本を並行して読んでいることがほとんどです。空き時間があれば本を読みたくなってしまうので、自分がよくいる場所には読みさしの本が大体2-3冊くらいはあります。その中から、その時の気分で読みたいものを読むという感じです。メインで読むのは鞄の中に入れている本なのですが、休みの日など頭がオフになっている場合、実家にいる場合、などなどその時に合わせて周りにある読みさしの本を読みだします。</p>
<p>いずれにしても欠かせないのは栞です。<strong>栞</strong>を忘れてしまうとどこから読み続きなのかを探すのに相当時間をロスしてしまいます。ハードカバー型だと紐の栞がついている場合もありますが、ない場合もあるので必ず用意します。個人的にはこだわりは何もないのでよく使うのは本についている読者アンケートのハガキです。ただ、１）で記載したように私は中古で買うことがほとんどなので、たまに本屋で買う時についてくる本にはさまっているハガキを使い回すことになります。</p>
<p>大体、こんなところです。<br />
	1冊の本を買ってから読み終わるまでには大体1-2か月くらいかと思います。実際に読書に着手するまでほったらかしておく期間もありますが、細切れにしか読まない本は読み終えるのにも相当時間がかかりますし、鞄の中に入れている本はやはり回転も速いです。1ヶ月に10-15冊くらいが私の平均的な読書量ですので、鞄の中の本は大体1週間に2冊くらい入れ替わり、色々な所（3-4か所くらいです）に置いてある読みさしの本がそれぞれ1ヶ月に1冊くらい入れ替わるような感じでしょうか。<br />
</p>
<p>さてようやく次回<br />
	<strong>3.1冊の本を読む際の読み方をどうしているか</strong><br />
にたどりつきました。ここはおそらく一番長くなりますので、1回では終わらないかもしれないですね。では、また。</p>]]>
   </content>
</entry>

</feed>
