<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xml:lang="ja">
  <channel>
    <title>unknownplace.org - memo</title>
    <link>http://unknownplace.org/memo/</link>
    <description>just my memo</description>
    <dc:creator>typester</dc:creator>
    <item>
      <title>ふるいPerlをいれる</title>
      <link>http://unknownplace.org/memo/2010/08/13/1/</link>
      <description><![CDATA[<p>perlbrew を導入したのでもりもりテスト環境を作れるようになったわけですが、perl-5.8.8 をいれようとしたら</p>
<pre><code>    Can&#39;t open makefile: No such file or directory.
    Can&#39;t open x2p/makefile: No such file or directory.
    make: *** No rule to make target `&#60;command-line&#62;&#39;, needed by `miniperlmain.o&#39;.  Stop.
    make: *** No rule to make target `&#60;command-line&#62;&#39;, needed by `miniperlmain.o&#39;.  Stop.
</code></pre>
<p>のように make がこけてしまってインストールできなかった。 ググってみるとどうも新しいgccだと古いPerlはうまくビルドできないらしい。</p>
<p>解決法としては makefile (OSXではGNUmakefile) の <code>command-line</code> を含む行は消してあげるというのでなんとかなるみたい。</p>
<p>以下のようにしてみた:</p>
<pre><code>$ ./Configure -de -Dprefix=$HOME/perl5/perlbrew/perls/5.8.8
$ perl -i~ -nle &#39;print unless /command-line/&#39; GNUmakefile x2p/GNUmakefile
$ make
$ make test
$ make install
</code></pre>
<p>これでちゃんとperlbrewからも認識できてて</p>
<pre><code>$ perlbrew switch 5.8.8
</code></pre>
<p>とかでswitchできました。まる。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Fri, 13 Aug 2010 00:05:00 GMT</pubDate>
      <category>osx, perl</category>
    </item>
    <item>
      <title>ユニバーサルバイナリ作成用シェルスクリプト</title>
      <link>http://unknownplace.org/memo/2010/07/27/1/</link>
      <description><![CDATA[<p>iPhone用にビルドしたライブラリは実機用(armv6/armv7)とシミュレータ用(i386)のユニバーサルバイナリとして作成しておくと使い勝手が良いです。 その分ビルドは面倒になるのですが。。</p>
<p>僕は通常以下のようにしてユニバーサルバイナリを作成してます。</p>
<ol><li>まずprefixをそれぞれ <code>~/dev/iphone/lib/curl-7.20.1-armv6</code> <code>~/dev/iphone/lib/curl-7.20.1-armv7</code> <code>~/dev/iphone/lib/curl-7.20.1-i386</code> などとしてそれぞれのアーキテクチャ用にビルドをする</li><li>適当に書いた <a href="http://gist.github.com/491799">bundle.sh</a> でユニバーサルバイナリ化</li></ol>
<p>この <code>bundle.sh</code> は上の例だと</p>
<pre><code>./bundle.sh ~/dev/iphone/lib/curl-7.20.1
</code></pre>
<p>として実行すると <code>~/dev/iphone/lib/curl-7.20.1-armv6</code> <code>~/dev/iphone/lib/curl-7.20.1-armv7</code> <code>~/dev/iphone/lib/curl-7.20.1-i386</code> が全部がっちゃんこした <code>~/dev/iphone/lib/curl-7.20.1</code> ができるという寸法です。</p>
<p>この方法だとまだ3つ分手動でビルドするのがめんどくさいので、そこも自動化したいところですね。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Tue, 27 Jul 2010 05:52:00 GMT</pubDate>
      <category>osx, iphone</category>
    </item>
    <item>
      <title>Text::MicroTemplate::DataSection</title>
      <link>http://unknownplace.org/memo/2010/07/03/1/</link>
      <description><![CDATA[<p><code>__DATA__</code> に</p>
<pre><code>__DATA__

@@ index.mt
&#60;<span class="function-name">html</span>&#62;
 &#60;<span class="function-name">body</span>&#62;Hello&#60;/<span class="function-name">body</span>&#62;
&#60;/<span class="function-name">html</span>&#62;

@@ bar.mt
? if ($true) {
  Foo
? }
</code></pre>
<p>こう言うのが書いてあるとき、<code>Data::Section::Simple</code> を使うと</p>
<pre><code>get_data_section(&#39;index.mt&#39;);
</code></pre>
<p>とすることで該当セクションだけのデータを簡単に取得することができます。 なので普通の <code>Text::MicroTemplate</code> と組み合わせても</p>
<pre><code>render_mt(get_data_section(&#39;index.mt&#39;));
</code></pre>
<p>って感じで使えてそんなに苦じゃないわけですが、どうせなら中で include とか extends とかで他のセクションのデータとも連携できるようにしたら便利だなーと思い3分クッキングして <code>Text::MicroTemplate::DataSection</code> と言うのを書いてみました。</p>
<p>使い方は簡単、</p>
<pre><code>use Text::MicroTemplate::DataSection &#39;render_mt&#39;;
</code></pre>
<p>とすると <code>Text::MicroTemplate::File</code> ベース、</p>
<pre><code>use Text::MicroTemplate::DataSectionEx &#39;render_mt&#39;;
</code></pre>
<p>とすると <code>Text::MicroTemplate::Extended</code> ベースの機能が使えるようになります。</p>
<p>あとは <code>render_mt(&#39;index.mt&#39;)</code> などとすれば <code>__DATA__</code> からテンプレート出力が行えます。基本ベースクラスのすべての機能がつかえますので、Exを使っている場合は、</p>
<pre><code>? extends &#39;base&#39;;

? block content =&#62; sub {
Hello!
? }
</code></pre>
<p>とか</p>
<pre><code>?= include &#39;hoge&#39;
</code></pre>
<p>とかもそのまま <code>__DATA__</code> のなかのテンプレートで使用することができます。Enjoy!</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Sat, 03 Jul 2010 03:20:00 GMT</pubDate>
      <category>perl</category>
    </item>
    <item>
      <title>PerlエンジニアのためのObjective-C Blocks入門</title>
      <link>http://unknownplace.org/memo/2010/05/11/1/</link>
      <description><![CDATA[<p>OS X 10.6 以降の xcode では Objective-C に Blocks というシンタックスが追加されている。</p>
<blockquote><p><a href="https://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40007502-CH1-SW1">Blocks Programming Topics: Introduction</a></p></blockquote>
<p>Perl でいうところの無名関数（コードブロック）を作ることができる機能で、Perlでいうところの</p>
<pre><code><span class="keyword">my</span> <span class="variable-name">$f</span> = <span class="keyword">sub</span> { ... };
$f-&#62;();
</code></pre>
<p>は</p>
<pre><code>void (^f)() = ^{ ... };
f();
</code></pre>
<p>のように書ける。書式がきもいのはObjective-Cの定めなのであきらめましょう。 より詳しい書式については上記ドキュメントを見ると良い。</p>
<p>しかしデフォルトではPerlのコードブロックとはレキシカル変数の扱いが異なる。</p>
<pre><code><span class="keyword">my</span> <span class="variable-name">$i</span> = 0;
<span class="keyword">my</span> <span class="variable-name">$f</span> = <span class="keyword">sub</span> { <span class="keyword">return</span> $i + 1 };

$i++;

$f-&#62;(); <span class="comment-delimiter"># </span><span class="comment">2 を返す
</span></code></pre>
<p>perlではこのようにレキシカル変数はコードブロック内と共有されるが、Objective-Cの場合は</p>
<pre><code>int i = 0;
int (^f)() = ^{ return i + 1; };

i++;

f(); // 1 を返す
</code></pre>
<p>このようになる。これはブロックを作成するときのレキシカル変数がコピーされるからである。 Perlとおなじような挙動を望む場合は <code>__block</code> ストレージタイプを指定すればいいようだ。</p>
<pre><code>__block int i = 0;
int (^f)() = ^{ return i + 1; };

i++;

f(); // 2
</code></pre>
<p>ここまでわかればObjective-CでBlockの再帰を書くことができる。</p>
<pre><code>__block void (^f)();
f = ^{ f(); };
f();
</code></pre>
<p>これは以下とおなじ、</p>
<pre><code><span class="keyword">my</span> <span class="variable-name">$f</span>;
$f = <span class="keyword">sub</span> { $f-&#62;() };
$f-&#62;();
</code></pre>
<p>というようにPerlエンジニアにとっては割と直感的なコードブロックが使えるようになっております。 書式がきもいことをのぞけばいい感じです。</p>
<p>次回は「PerlエンジニアのためのGrand Central Dispatch」の予定です。</p>
<h4>追記＠2010-05-11T19:12:48+09:00</h4>
<blockquote><p><a href="http://b.hatena.ne.jp/entry/unknownplace.org/memo/2010/05/11/1/">はてなブックマーク - PerlエンジニアのためのObjetive-C Blocks - unknownplace.org</a></p><p>lyokato 「Objective-Cの仕様というよりは、Blocks拡張に対応したCコンパイラの仕様かな」</p></blockquote>
<p>ってことでやってみたら</p>
<pre><code>#include &#60;stdio.h&#62;

int main(int argc, char** argv) {
    void (^f)() = ^{ printf(&#34;Hello Blocks!\n&#34;); };
    f();

    return 0;
}

// $ gcc foo.c
// $ ./a.out
</code></pre>
<p>でも行けました。gcc の拡張なんですね。あざっす！</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Tue, 11 May 2010 05:29:00 GMT</pubDate>
      <category>objc, perl</category>
    </item>
    <item>
      <title>qpsmtpd を Server::Starter 化するなど</title>
      <link>http://unknownplace.org/memo/2010/03/24/1/</link>
      <description><![CDATA[<p>Perl 製 SMTP サーバーとして <a href="http://smtpd.develooper.com/">qpsmtpd</a> というものがあり、僕もいろいろなところで利用している。主な用途としてはメール連動の Web アプリケーションのメール機能の部分。実際のメール配送などでは使用してない。</p>
<p>フロントに qpsmtpd を置き、アプリで制御する宛先の場合のみ qpsmtpd からジョブキューに流したりする。 それ以外の通常のメールは <code>queue/postfix</code> プラグインなどを使用して裏側の postfix にまかせちゃう。というような使い方をしている。</p>
<p>qpsmtpd 自体は apache.org や perl.org の SMTP として採用されており、パフォーマンスに関しては問題ないのだが、プラグインを書き換えたり設定を変更したりした場合に再起動が必要になるところが、フロントに立てるサーバーとしては不安な部分であった。</p>
<p>なので前々から Server::Starter 対応はしたいとおもっていたが安定動作している既存のサーバーで作業する機会も特になく放置していた。</p>
<p>そしてこのたびめでたく新しく qpsmtpd を設置することになったためいっちょやったるか、となった次第である。</p>
<p>この辺で作業：</p>
<blockquote><p><a href="http://github.com/typester/qpsmtpd/commits/topic/server_starter">http://github.com/typester/qpsmtpd/commits/topic/server_starter</a></p></blockquote>
<p>使い方は：</p>
<pre><code># start_server --port=25 --port=127.0.0.1:20025 -- ./qpsmtpd-async-server-starter
</code></pre>
<p>このような感じで、SMTP用のポートと、qpsmtpd 制御用の contig ポートを同時に渡して起動する。その後 <code>Server::Starter</code> の superdaemon にたいし HUP シグナルを送ると graceful restart できる。</p>
<p>古い worker プロセスでは最大 <code>$TIMEOUT</code> 秒（デフォルト60）だけ既存の接続を終了まで待つ、graceful shutdown 機能も併せて実装したので完全にダウンタイムをなくせているはず。</p>
<p>とりあえずあまりテストしきれてないけどドッグフードを食べてがんばろうと思います。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Wed, 24 Mar 2010 13:38:00 GMT</pubDate>
      <category>perl, qpsmtpd</category>
    </item>
    <item>
      <title>GNU screen の裏にいる Window で完了したコマンドを Growl 通知したい</title>
      <link>http://unknownplace.org/memo/2010/03/23/1/</link>
      <description><![CDATA[<p>というようなことをつぶやいていたら、</p>
<blockquote><p><a href="http://twitter.com/hchbaw/status/9921025674">Twitter / hchbaw: @typester 最近になって screen -Q windows とできるようになってますね。</a></p></blockquote>
<p>と教えていただいた。</p>
<p><code>-Q</code> コマンドというのは <code>-X</code> と同じようなものだけど、コマンド結果を screen 内のステータス領域ではなく標準出力で得ることができる。また、<code>-X</code> はつねに実行時にそれ自体がアクティブな screen セッションになるのに対し <code>-Q</code> はアクティブなセッションにクエリを投げる感じで、セッションが切り替わらない。（この辺は理解が怪しいので突っ込み歓迎）</p>
<p>それでそれを使うと</p>
<pre><code>screen -Q windows
</code></pre>
<p>と実行することで <code>:windows</code> で echo されるのとおなじ文字列を標準出力で得ることができる。その出力をパースすれば、自分が screen の裏にいるかどうか判断することができるというわけ。</p>
<p>zsh でコマンド完了時（正確にはプロンプトが表示される直前）に呼ばれるフックは <code>precmd</code> なので以下のように定義：</p>
<pre><code>function precmd() {
    $HOME/bin/precmd.pl `history -n -1 | head -1`
}
</code></pre>
<p>シェルスクリプトかけないので Perl に逃げています。 で、precmd.pl は以下のような感じ：</p>
<pre><code><span class="comment-delimiter">#</span><span class="comment">!/usr/bin/perl
</span>
<span class="keyword">use</span> <span class="function-name">strict</span>;
<span class="keyword">use</span> <span class="function-name">warnings</span>;
<span class="keyword">use</span> <span class="function-name">FileHandle</span>;

<span class="keyword">my</span> <span class="variable-name">$lastcmd</span> = <span class="type">join</span> <span class="string">&#39; &#39;</span>, <span class="cperl-array">@ARGV</span>;

<span class="keyword">my</span> <span class="variable-name">$window</span> = <span class="cperl-hash">$ENV</span>{<span class="string">WINDOW</span>};

<span class="keyword">my</span> <span class="variable-name">$windows</span> = <span class="cperl-nonoverridable">qx</span><span class="string">{ screen -Q windows }</span> <span class="type">or</span> <span class="keyword">die</span> <span class="string">&#34;Your screen doesn&#39;t support -Q&#34;</span>;
<span class="cperl-nonoverridable">qx</span><span class="string">{ screen -X redisplay }</span>;

<span class="keyword">my</span> <span class="variable-name">$active</span>;
<span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$win</span> (<span class="cperl-nonoverridable">split</span> <span class="string">&#34;\x20\x20&#34;</span>, $windows) {
    <span class="keyword">my</span> (<span class="variable-name">$num</span>, <span class="variable-name">$flag</span>, <span class="variable-name">$title</span>) = $win =~ <span class="constant">/</span><span class="function-name">^</span><span class="keyword">(</span><span class="builtin">\</span><span class="type">d</span><span class="builtin">+</span><span class="keyword">)(</span><span class="function-name">.</span><span class="keyword">)</span><span class="builtin">?</span><span class="string"> </span><span class="keyword">(</span><span class="function-name">.</span><span class="builtin">+</span><span class="keyword">)</span><span class="constant">/</span>;

    <span class="keyword">if</span> ($flag <span class="type">and</span> $flag <span class="type">eq</span> <span class="string">&#39;*&#39;</span>) {
        $active = $num;
        <span class="keyword">last</span>;
    }
}

<span class="keyword">if</span> ($window <span class="negation-char">!</span>= $active) {
    <span class="type">open</span> <span class="keyword">my</span> <span class="variable-name">$fh</span>, <span class="string">&#34;|/usr/local/bin/growlnotify -t &#39;GNU screen window $window&#39;&#34;</span> <span class="type">or</span> <span class="keyword">die</span> $!;
    <span class="cperl-nonoverridable">print</span> $fh <span class="type">sprintf</span> <span class="string">&#39;command done: &#34;</span><span class="cperl-hash">%s</span><span class="string">&#34;&#39;</span>, $lastcmd;
    <span class="cperl-nonoverridable">print</span> $fh <span class="string">&#34;\n&#34;</span>;
    <span class="type">close</span> $fh;
}
</code></pre>
<p>これで、コマンドが完了した場合にピコーンと通知が来るようになりました。</p>
<p>長い make や wget の時に超絶便利ですね！</p>
<p>書き忘れましたが、現在この機能をつかうためには開発版の screen を使用する必要があります。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Tue, 23 Mar 2010 02:22:00 GMT</pubDate>
      <category>screen, zsh</category>
    </item>
    <item>
      <title>yokohama.pm tech talk #5</title>
      <link>http://unknownplace.org/memo/2010/03/06/1/</link>
      <description><![CDATA[<p>OpenSocial なモバイルアプリを書く場合、アプリ単体でテストできるようにしてくれる Moxy の OpenSocial プラグインの話と、外部 API 呼び出しを専用に行う非同期なプロクシサーバーの話をしました。</p>
<p>資料はこちら:</p>
<blockquote><p><a href="http://typester.stfuawsc.com/slides/yokohamapm5/start.html">OpenSocial mobile application development</a></p></blockquote>
<p>前者に関しては、個人的には OpenSocial モバイルアプリ開発には必須なツールなので良い感じにしていきたいところ。 ＆してくれるひと募集。</p>
<p>後者のプロクシサーバーは「あんまり頭よくない」だけれども、現在のウェブアプリケーションの構成で、API呼び出しの待ち時間をうまく使おうとするときにはこうなるのかなぁと思った。同じようなことをしているところもあるらしい！</p>
<p>個人的にはそれ〜でできるよ！ってのがないかなーと思っていたのだけど、ないっぽいのかなー。</p>
<p>nginx でおしいところまではできるので、モジュール書いたら出来るのか調べてみようと思う。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Sat, 06 Mar 2010 04:19:00 GMT</pubDate>
      <category>perl, yokohama.pm</category>
    </item>
    <item>
      <title>local::lib を切り替える</title>
      <link>http://unknownplace.org/memo/2010/03/01/1/</link>
      <description><![CDATA[<p>レガシーなアプリをメンテするのにレガシーな Perl モジュールが必要になることがあり、そのために古いアプリ用には専用の <code>local::lib</code> ディレクトリを切っているわけですが、普段から日常的に <code>local::lib</code> を使用しているため shell が上がったタイミングではデフォルトの <code>local::lib</code> 環境変数がセットされていて切り替えが非常に面倒だった。</p>
<p>これまではそれほど頻繁に使用しなかったので放置していたのだが、ここのところ頻繁に必要になるためいい加減うざくなってきて簡単に <code>local::lib</code> を切り替えられるよう設定をしてみた。</p>
<p>zsh に次のような関数をつくり、それで <code>local::lib</code> を切り替えるようにする。</p>
<pre><code>function locallib () {
    INSTALL_BASE=$1
    if [ -d $INSTALL_BASE ]; then
        eval $(~/bin/use-locallib $INSTALL_BASE)
    fi
}
</code></pre>
<p>これは</p>
<pre><code>$ locallib ~/perl5
</code></pre>
<p>などのように <code>INSTALL_BASE</code> を指定して使う。指定されたパスが存在したら <code>use-locallib</code> というコマンドを使用して環境変数を切り替えるという内容。</p>
<p>この <code>use-locallib</code> コマンドは以下のようなソースになっていて、古い <code>local::lib</code> の環境変数をクリアするとともに、新しい <code>local::lib</code> の環境変数を <code>print</code> するというものになっている。</p>
<pre><code><span class="comment-delimiter">#</span><span class="comment">!/usr/bin/env perl
</span>
<span class="keyword">use</span> <span class="function-name">strict</span>;
<span class="keyword">use</span> <span class="function-name">warnings</span>;
<span class="keyword">use</span> <span class="function-name">Pod::Usage</span>;

<span class="keyword">use</span> <span class="function-name">Config</span>;
<span class="keyword">use</span> <span class="function-name">File::Spec</span>;

<span class="keyword">my</span> <span class="variable-name">$install_base</span> = <span class="cperl-array">$ARGV</span>[0]
    <span class="type">or</span> pod2usage(-1);

$install_base = File::Spec-&#62;rel2abs($install_base);

<span class="keyword">my</span> <span class="variable-name">$path</span>     = <span class="cperl-hash">$ENV</span>{<span class="string">PATH</span>};
<span class="keyword">my</span> <span class="variable-name">$perl5lib</span> = <span class="cperl-hash">$ENV</span>{<span class="string">PERL5LIB</span>};

<span class="cperl-nonoverridable">push</span> <span class="cperl-array">@INC</span>, File::Spec-&#62;catdir($install_base, <span class="string">&#39;lib&#39;</span>, <span class="string">&#39;perl5&#39;</span>);

<span class="keyword">require</span> <span class="keyword">local</span>::lib;
<span class="keyword">my</span> <span class="cperl-hash">%env</span> = <span class="keyword">local</span>::lib-&#62;build_environment_vars_for($install_base, 1);

<span class="comment-delimiter"># </span><span class="comment">remove $PERL5LIB set by old local::lib if it exists.
</span><span class="keyword">if</span> (<span class="keyword">my</span> <span class="variable-name">$old_base</span> = <span class="cperl-hash">$ENV</span>{<span class="string">PERL_MM_OPT</span>}) {
    <span class="keyword">my</span> <span class="cperl-hash">%mmopt</span>;
    <span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$opt</span> (<span class="cperl-nonoverridable">split</span> <span class="constant">/</span><span class="string">:</span><span class="builtin">+</span><span class="constant">/</span>, $old_base) {
        <span class="keyword">my</span> (<span class="variable-name">$k</span>, <span class="variable-name">$v</span>) = <span class="cperl-nonoverridable">split</span> <span class="constant">/</span><span class="string">=</span><span class="constant">/</span>, $opt;
        <span class="cperl-hash">$mmopt</span>{$k} = $v;
    }

    <span class="keyword">if</span> (<span class="keyword">my</span> <span class="variable-name">$old_installbase</span> = <span class="cperl-hash">$mmopt</span>{<span class="string">INSTALL_BASE</span>}) {
        <span class="keyword">if</span> ($old_installbase <span class="type">eq</span> $install_base) {
            <span class="comment-delimiter"># </span><span class="comment">do nothing if install_base is equal to old one
</span>            <span class="keyword">exit</span>;
        }

        <span class="keyword">my</span> <span class="cperl-array">@old_perl5lib</span> = (
            File::Spec-&#62;catdir($old_installbase, <span class="string">&#39;lib&#39;</span>, <span class="string">&#39;perl5&#39;</span>),
            File::Spec-&#62;catdir($old_installbase, <span class="string">&#39;lib&#39;</span>, <span class="string">&#39;perl5&#39;</span>, <span class="cperl-hash">$Config</span>{<span class="string">archname</span>}),
        );

        <span class="cperl-hash">$env</span>{<span class="string">PERL5LIB</span>} = <span class="keyword">do</span> {
            <span class="keyword">my</span> <span class="cperl-array">@env</span>;
            <span class="constant">ENV:</span> <span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$e</span> (<span class="cperl-nonoverridable">grep</span> { $_ } <span class="cperl-nonoverridable">split</span> <span class="cperl-hash">$Config</span>{<span class="string">path_sep</span>}, <span class="cperl-hash">$env</span>{<span class="string">PERL5LIB</span>}) {
                <span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$old</span> (<span class="cperl-array">@old_perl5lib</span>) {
                    <span class="keyword">next</span> <span class="constant">ENV</span> <span class="keyword">if</span> $old <span class="type">eq</span> $e;
                }
                <span class="cperl-nonoverridable">push</span> <span class="cperl-array">@env</span>, $e;
            }
            <span class="type">join</span> <span class="cperl-hash">$Config</span>{<span class="string">path_sep</span>}, <span class="cperl-array">@env</span>;
        };

        <span class="keyword">my</span> <span class="variable-name">$old_path</span> = File::Spec-&#62;catdir($old_installbase, <span class="string">&#39;bin&#39;</span>);
        <span class="cperl-hash">$env</span>{<span class="string">PATH</span>} = <span class="keyword">do</span> {
            <span class="keyword">my</span> <span class="cperl-array">@p</span>;
            <span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$p</span> (<span class="cperl-nonoverridable">grep</span> {$_} <span class="cperl-nonoverridable">split</span> <span class="cperl-hash">$Config</span>{<span class="string">path_sep</span>}, <span class="cperl-hash">$env</span>{<span class="string">PATH</span>}) {
                <span class="keyword">next</span> <span class="keyword">if</span> $p <span class="type">eq</span> $old_path;
                <span class="cperl-nonoverridable">push</span> <span class="cperl-array">@p</span>, $p;
            }
            <span class="type">join</span> <span class="cperl-hash">$Config</span>{<span class="string">path_sep</span>}, <span class="cperl-array">@p</span>;
        };
    }
}

<span class="keyword">while</span> (<span class="keyword">my</span> (<span class="variable-name">$k</span>, <span class="variable-name">$v</span>) = <span class="cperl-nonoverridable">each</span> <span class="cperl-hash">%env</span>) {
    <span class="cperl-nonoverridable">print</span> <span class="cperl-nonoverridable">qq</span><span class="string">[export $k=&#34;$v&#34;\n]</span>;
}
<span class="comment">
=head1 </span><span class="variable-name">NAME</span><span class="comment">

use-locallib - set/switch local::lib environment

=head1 </span><span class="variable-name">SYNOPSIS</span><span class="comment">

use-locallib (MODULE INSTALL BASE)
</span></code></pre>
<p>これで <code>local::lib</code> を簡単に切り替えられるようになるけれど、複数の <code>local::lib</code> 環境を同時に使用しているとどのシェルがどの <code>local::lib</code> を使用しているかわからなくなってしまう。</p>
<p>そのためシェルのプロンプトに <code>INSTALL_BASE</code> を表示されるようにしてしのいだ。</p>
<p><a href="http://www.flickr.com/photos/typester/4397750144/" title="show INSTALL_BASE in terminal prompt by typester, on Flickr"><img alt="show INSTALL_BASE in terminal prompt" height="100" src="http://farm3.static.flickr.com/2758/4397750144_cd22b17a99_o.png" width="280" /></a></p>
<p>これは単純に以下のような <code>PERL_MM_OPT</code> の <code>INSTALL_BASE</code> をプリントするスクリプトを PROMPT 設定から読んでいるだけである。</p>
<pre><code><span class="comment-delimiter">#</span><span class="comment">!/usr/bin/env perl
</span>
<span class="keyword">use</span> <span class="function-name">strict</span>;
<span class="keyword">use</span> <span class="function-name">warnings</span>;

<span class="keyword">my</span> <span class="cperl-hash">%mm_opt</span>;
<span class="keyword">for</span> <span class="keyword">my</span> <span class="variable-name">$opt</span> (<span class="cperl-nonoverridable">split</span> <span class="constant">/</span><span class="string">:</span><span class="builtin">+</span><span class="constant">/</span>, <span class="cperl-hash">$ENV</span>{<span class="string">PERL_MM_OPT</span>} || <span class="string">&#39;&#39;</span>) {
    <span class="keyword">my</span> (<span class="variable-name">$k</span>, <span class="variable-name">$v</span>) = <span class="cperl-nonoverridable">split</span> <span class="constant">/</span><span class="string">=</span><span class="constant">/</span>, $opt;
    <span class="cperl-hash">$mm_opt</span>{$k} = $v;
}

<span class="keyword">my</span> <span class="variable-name">$install_base</span> = <span class="cperl-hash">$mm_opt</span>{<span class="string">INSTALL_BASE</span>};
<span class="keyword">if</span> (<span class="cperl-hash">$ENV</span>{<span class="string">HOME</span>}) {
    $install_base =~ <span class="cperl-nonoverridable">s</span><span class="constant">/</span><span class="function-name">^</span><span class="cperl-hash">$ENV</span><span class="variable-name">{</span><span class="string">HOME</span><span class="variable-name">}</span><span class="constant">/</span><span class="string">~</span><span class="constant">/</span>;
}

<span class="cperl-nonoverridable">print</span> $install_base || <span class="string">&#39;none&#39;</span>;
</code></pre>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Mon, 01 Mar 2010 08:17:00 GMT</pubDate>
      <category>perl, zsh</category>
    </item>
    <item>
      <title>ライブラリをユニバーサルバイナリでインストールする</title>
      <link>http://unknownplace.org/memo/2010/01/08/2/</link>
      <description><![CDATA[<p>以下のサイトが詳しい</p>
<blockquote><p><a href="http://macwiki.sourceforge.jp/wiki/index.php/UniversalBinary">http://macwiki.sourceforge.jp/wiki/index.php/UniversalBinary</a></p></blockquote>
<p><code>Imager</code> に必要な <code>libjpeg</code> などをユニバーサルバイナリにしてみた時のメモ</p>
<p><code>-M</code> などがついていて <code>-arch</code> が複数指定できない場合以外は</p>
<pre><code>CFLAGS=&#39;-arch x86_64 -arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk&#39; CXXFLAGS=$CFLAGS
</code></pre>
<p>とかすればいいということだが、<code>libjpeg</code> は <code>-M</code> られていて無理だったので、amd64 と i386 という二つのディレクトリにソースコードを展開、それぞれ以下のオプションで make まで終わらす：</p>
<pre><code>$ cd amd64
$ CFLAGS=&#39;-arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk&#39; CXXFLAGS=$CFLAGS ./configure ...
$ make

$ cd ../i386
$ CFLAGS=&#39;-arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk&#39; CXXFLAGS=$CFLAGS ./configure ...
$ make
</code></pre>
<p>make されてできたバイナリを lipo コマンドでユニバーサルバイナリ化する。 上記サイトを参考にして、</p>
<pre><code>#!/bin/sh

filelist=$(find ./amd64 -type f |grep -v \\.o$ | xargs file | sed -e &#39;s,^\./amd64/,,g&#39; | \
               grep -E \(Mach-O\)\|\(ar\ archive\) |sed -e &#39;s,:.*,,g&#39; -e &#39;/\for\ architecture/d&#39;)

for i in $filelist
do
    echo $i
    /usr/bin/lipo -create amd64/$i i386/$i -output `basename $i`
    mv -f `basename $i` amd64/$i
done
</code></pre>
<p>このようなスクリプトを書いて、amd64 などのディレクトリの一つ上の階層で実行すると、amd64 ディレクトリのバイナリがユニバーサルバイナリ化されるという仕組みを作ってみた。</p>
<p>その後、amd64 のほうで <code>make install</code> してやれば OK。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Fri, 08 Jan 2010 02:28:00 GMT</pubDate>
      <category>osx</category>
    </item>
    <item>
      <title>Snow Leopard の Perl とアーキテクチャ</title>
      <link>http://unknownplace.org/memo/2010/01/08/1/</link>
      <description><![CDATA[<p>Snow Leopard には二つの Perl がインストールされている</p>
<ul><li>/usr/bin/perl5.10.0</li><li>/usr/bin/perl5.8.9</li></ul>
<p>デフォルトの <code>/usr/bin/perl</code> は 5.10.0 のほう。それぞれユニバーサルバイナリになっていて、</p>
<pre><code>$ file /usr/bin/perl5.10.0
/usr/bin/perl5.10.0: Mach-O universal binary with 3 architectures
/usr/bin/perl5.10.0 (for architecture x86_64):  Mach-O 64-bit executable x86_64
/usr/bin/perl5.10.0 (for architecture i386):    Mach-O executable i386
/usr/bin/perl5.10.0 (for architecture ppc7400): Mach-O executable ppc

$ file /usr/bin/perl5.8.9
/usr/bin/perl5.8.9: Mach-O universal binary with 2 architectures
/usr/bin/perl5.8.9 (for architecture i386):     Mach-O executable i386
/usr/bin/perl5.8.9 (for architecture ppc7400):  Mach-O executable ppc
</code></pre>
<p>という感じで、5.10 は 64bit 版があるが、5.8 にはない。</p>
<p>で、普通に perl を実行すると perl5.10.0 は <code>x86_64</code> で実行され、perl5.8.9 は <code>i386</code> で実行される。</p>
<p>このアーキテクチャの差が結構くせ者で Snow Leopard 上で普通にライブラリなどを make すると <code>x86_64</code> だけでビルドされてしまうため、そのようにして作ったライブラリはそのままでは perl5.8.9 からは使えないということになる。</p>
<p>デフォルトの 5.10.0 だけ使っている分にはなにも問題はないのだが、残念なことにこの 5.10.0 というのはいろいろな問題があり、開発に使用することはおすすめできない状況。(せめて 5.10.1 にしてくれればいいのに)</p>
<p>したがって無用なトラブルを避けるためにも 5.8.9 の方を使用するか、自前でビルドした perl を使用するのが良い。</p>
<p>またこのように <code>x86_64</code>、<code>i386</code> 両方のアーキテクチャの実行ファイルがあり得る Snow Leopard に対して自分でライブラリをインストールする場合それらもユニバーサルバイナリにしておくと良い。</p>
<p>念のため追記＠2010-01-08T15:19:23+09:00: もちろんこれは 64bit 対応の CPU の場合の話。そうでない場合はどちらも i386 で実行されるのでこの問題は起こらない。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Fri, 08 Jan 2010 01:51:00 GMT</pubDate>
      <category>osx, perl</category>
    </item>
    <item>
      <title>CocoaEmacs おかしいところ</title>
      <link>http://unknownplace.org/memo/2009/12/24/2/</link>
      <description><![CDATA[<p>anything-config.el も無事なおり、Shiftのバグなおして日本語入力も快適になり、あとはまぁだいたいいい感じに使えるようになった(現状では) CocoaEmacs だけど一点だけおかしいところがある。</p>
<p>僕は結構 Emacs の customize 機能をヘビーユーズしてて（コーディングしてて気に入らない色設定とか出てきたらその場ですぐ customize-face する）これで色設定はほぼ調整してるのだけど、customize するのをすべての Emacs で同じものを使うのは微妙なので、</p>
<pre><code>(setq custom-file <span class="string">"~/.emacs.d/conf/cocoa-emacs-99customize.el"</span>)
</code></pre>
<p>のようにして、 customize の保存先を Emacs 毎に変えている。</p>
<p>のだけどこれが、<code>init-loader</code> のフェーズで <code>(load custom-file)</code> しても設定が適用されないという現象に悩まされている。</p>
<p>立ち上がったあとに手動で <code>(load custom-file)</code> するとロードされる。。なぞ。</p>
<p>しょうがないので、</p>
<pre><code>(<span class="keyword">defun</span> <span class="function-name">reload-custom-file</span> ()
  (interactive)
  (load custom-file))
</code></pre>
<p>こんなの作っておいて起動後手動で実行している。不毛だけどまぁ Emacs たちあげっぱだからいいかなぁ。。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Thu, 24 Dec 2009 08:58:00 GMT</pubDate>
      <category>emacs</category>
    </item>
    <item>
      <title>elispエラーった時の追い方</title>
      <link>http://unknownplace.org/memo/2009/12/24/1/</link>
      <description><![CDATA[<p>(setq debug-on-error t)</p>
<p>しておいて、<code>eval-bufer</code>。StackTrace 出るのでそれを見る。</p>
<p>Emacs 23 にしたら anything-config.el が <code>Invalid depth in char-table</code> とかいって死ぬようになったけど原因わからなくてこまってたけどこれやったら <code>~/.emacs.d/anything-c-adaptive-history</code> のロードに失敗してるのがわかった。消したらなおりました。imakado++</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Thu, 24 Dec 2009 08:48:00 GMT</pubDate>
      <category>emacs</category>
    </item>
    <item>
      <title>CocoaEmacsその後</title>
      <link>http://unknownplace.org/memo/2009/12/18/1/</link>
      <description><![CDATA[<p>フルスクリーン化以外にもいじりたくなったのでそれぞれブランチを切った。</p>
<ul><li><a href="http://github.com/typester/emacs/tree/feature/fullscreen">feature/fullscreen</a> - 今まで作業していたフルスクリーン化対応ブランチ</li><li><a href="http://github.com/typester/emacs/tree/fix/shift_modifier_with_ime">fix/shift_modifier_with_ime</a> - IME経由で入力するときShiftなんちゃらがIMEを素通りするのを直すブランチ</li></ul>
<p>という感じになっています。 master はこれらの統合ブランチになってますので使ってる人いたら注意です。</p>
<p>使いながらちょいちょいいじっていて、昨日からの更新としては</p>
<ul><li>フルスクリーン時に裏にノーマルなウィンドウが残ってしまっていたのを修正</li><li>日本語入力時に Shift なんちゃらが IME をとおらずそのまま Emacs に渡されてしまっているのを修正</li></ul>
<p>という感じになっております。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Fri, 18 Dec 2009 04:03:00 GMT</pubDate>
      <category>emacs, osx</category>
    </item>
    <item>
      <title>CocoaEmacsのフォント設定</title>
      <link>http://unknownplace.org/memo/2009/12/17/2/</link>
      <description><![CDATA[<p>現状こんな感じ。以前書いた<a href="http://unknownplace.org/memo/2009/01/20/2/">CarbonEmacsの設定</a>と大して変わってない。unicode コードセットで表示される文字が増えていたのでそれに対応した程度。</p>
<pre><code>(create-fontset-from-fontset-spec
 (concat
  <span class="string">"-*-fixed-medium-r-normal--12-*-*-*-*-*-fontset-tobi"</span>
  <span class="string">",ascii:-apple-codingfonttobi-medium-r-normal--16-120-72-72-m-120-*-*"</span>
  <span class="string">",japanese-jisx0208:-apple-osaka-*"</span>
  <span class="string">",katakana-jisx0201:-apple-osaka-*"</span>
  <span class="string">",unicode:-apple-osaka-*"</span>
  <span class="string">",chinese-big5-1:-apple-apple ligothic medium-*"</span>
  ))

(set-default-font <span class="string">"fontset-tobi"</span>)
</code></pre>
<p>ascii 用につかってる CodingFontTobi は <a href="http://www.proggyfonts.com/">proggyfonts.com</a> から。</p>
<p>もちろんビットマップ表示にするため</p>
<pre><code>$ defaults write org.gnu.Emacs AppleAntiAliasingThreshold 16
</code></pre>
<p>としている。</p>
<pre><code>(setq mac-allow-anti-aliasing nil)
</code></pre>
<p>は Snow Leopard では効かないみたいだ。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Thu, 17 Dec 2009 14:50:00 GMT</pubDate>
      <category>emacs, osx</category>
    </item>
    <item>
      <title>フルスクリーン Cocoa Emacs</title>
      <link>http://unknownplace.org/memo/2009/12/17/1/</link>
      <description><![CDATA[<p>emacs23 が正式にリリースされ、ちまたではウィンドウシステムが Cocoa になったぞ、とか 64bit 対応だぞ、とか multitty だぞ、と盛り上がっていますが、 個人的にほとんど興味のないまま今日まできました。というのも CocoaEmacs は<em>フルスクリーンにできない</em>という僕にとっては致命的な問題があったからです。</p>
<p>というのも最近は Emacs をフルスクリーンにし縦二分割で使ういわゆる imakado スタイルを実践しているため、それができない CocoaEmacs は眼中になかったのでした。</p>
<p>そんなわけでずっと CarbonEmacs を使ってきたのですが、 Snow Leopard に移行したのを機に CocoaEmacs に移行し、さらについでにフルスクリーン化できるようにしてみています。 github でやってます。</p>
<blockquote><p><a href="http://github.com/typester/emacs">typester&#39;s emacs at master - GitHub</a></p></blockquote>
<p>現状でも若干不具合がありますが、使える段階にはなっていると思います。</p>
<p>ビルドは</p>
<pre><code>$ git clone git://github.com/typester/emacs.git
$ cd emacs
$ ./configure --with-ns
$ make bootstrap
$ make install
</code></pre>
<p>こんな感じにすると、<code>nextstep</code> ディレクトリ以下に <code>Emacs.app</code> ができます。フルスクリーンにするには</p>
<pre><code>M-x ns-toggle-fullscreen
</code></pre>
<p>でいけます。キー割り当てておくと便利です。</p>
<p>対応環境は定かではありませんが、OS X 10.4 と 10.6 で動作確認しております。</p>
<p>また 10.6 の場合のみ、フルスクリーン時に隠れているメニューバーや Dock 領域にマウスカーソルを移動させると自動的に表示されるようになっています。 CarbonEmacs と違い Dock も自動で表示されるので個人的に非常に便利です。10.6 からの新 API のため、10.5 以前ではフルスクリーン時にメニューバー、Dock は強制オフになります。</p>
<p>既知の不具合として外部ウィンドウでフルスクリーン化して戻そうとすると落ちるというのが報告されており調査中です。 それ以外は便利に使用できています。この文章もフルスクリーン CocoaEmacs で書いています ;)</p>
<p>またこのハックをしたことで elisp から C や Objective-C のコードを呼ぶ方法がわかったのでいろいろ夢がひろがりんぐというところです。</p>
]]></description>
      <dc:creator>typester</dc:creator>
      <pubDate>Thu, 17 Dec 2009 11:27:00 GMT</pubDate>
      <category>emacs, osx</category>
    </item>
  </channel>
</rss>
