Blog, The

1 月 22 日生まれ、ブログ座です。

Mac の pbcopy, pbpaste がすごく便利

Mac の pbcopy, pbpaste ってコマンドがすごく便利だと思うんだけど、あまり認知されてないような。そんなことない?

たとえば SQL の実行結果をそのままクリップボードに入れたり、

$ cat foo.sql | mysql -uhoge -p --skip-column fuga | pbcopy

あと Excel とか Word とかの内容コピって加工したりとか。

$ pbpaste | some-filter | pbcopy

一旦ファイルに吐き出したり、ターミナルで範囲選択してコピーとかしなくていいから便利。 (特にスクロールするような時は面倒)

NetBSD インストールメモ

1年前ぐらいのメモ。結構色々書いてるのに下書きのままだったので公開してみる。

最近 Micro SD に NetBSD仮想マシンを放り込んで持ち歩くってことをしてて、環境構築で何かとつまづいたのでメモ。

NetBSD のインストール

Full Installation を選択。

最初は Custom Instllation で最小限の構成となるようにしてたんですが、

  • gcc が入ってなくてパッケージのインストールで詰む。
  • コンパイラ入れたのはいいけど X11 関連のエラーが出まくって詰む。

と、僕の知識じゃ何かと詰んでしまう感じなので、おとなしく身の丈にあった Full Installation を選ぶことにしました。

ネットワークの設定

仮想化には VirtualBox を使ってます。
ネットワークは様々な構成を選択できるんですが、今回はホスト OS とのやり取りはホストオンリーネットワーク、外部とのやり取りは NAT を使うことにしました。

まずはホストオンリー。こいつは固定 IP にします。
/etc/ifconfig.wm0 (wm0 はインターフェース名。環境によって変わるかも) を以下の内容で作成します。

192.168.56.201 netmask 255.255.255.0 media autoselect

続いて NAT。こいつは DHCP にしました。
/etc/rc.conf に以下の内容を追記します。

dhclient=YES
dhclient_flags="wm1"

その他 rc.conf の設定

/etc/rc.conf に以下を追加。
ホストネームの設定、SSH サーバーの有効化、BIOS 時刻を現地時間として使用するように設定してます。

hostname=netbsd
sshd=YES
rtclocaltime=YES

pkgsrc のインストール

NetBSD の標準パッケージ管理ツール。
FTP からダウンロードして、/usr 以下に展開します。

# ftp ftp://ftp.NetBSD.org/pub/pkgsrc/current/pkgsrc.tar.gz
# tar -xzf pkgsrc.tar.gz -C /usr

インストールするパッケージのディレクトリ (/usr/pkgsrc/{カテゴリ}/{パッケージ} みたいな感じ) に移動して、make install するってのが基本的な使い方のようです。

インストールしたパッケージは /usr/pkg 以下に設置されます。

各種パッケージのインストール

bash

ログインシェルは bash がいいのでインストール。
zsh はいつか試す。いつか。

# cd /usr/pkgsrc/shells/bash
# make install && make clean clean-depends
sudo

セキュリティっていうより、単純に使用感に慣れちゃってるのでインストール。

# cd /usr/pkgsrc/security/sudo
# make install && make clean clean-depends

wheel グループのユーザーに対して、sudo の実行を許可するよう設定します。
visudo で sudoers ファイルの以下の行をコメントアウトします。

%wheel ALL=(ALL) ALL
emacs

GUI は不要なので emacs じゃなくて emacs-nox11 っていうパッケージにしました。

# cd /usr/pkgsrc/editors/emacs-nox11
# make install && make clean clean-depends
git

デフォルトだと GUI のツールもインストールされるらしい。
不要であれば、事前に /etc/mk.conf (なければ作成) に以下の行を追加しとく。

PKG_OPTIONS.scmgit=-scmgit-gui

あとは普通にインストール。

# cd /usr/pkgsrc/devel/scmgit
# make install && make clean clean-depends
mozilla-rootcerts

git で httpsリポジトリをクローンするときとかにエラーになっちゃうので、ルート証明書をインストールしとく。

# cd /usr/pkgsrc/security/mozilla-rootcerts
# make install && make clean clean-depends

インストールしたルート証明書を OpenSSL のディレクトリに展開。

# cd /etc/openssl/certs
# mozilla-rootcerts extract
# mozilla-rootcerts rehash
sun-jdk6

Java のプログラムを書くことは滅多にないけど、Closure Compiler とかは使うので。

事前に Oracle のサイトから以下のファイルをダウンロードし、/usr/pkgsrc/distfiles に設置しておきます。

加えて、/etc/mk.conf に以下を追記します。

ACCEPTABLE_LICENSES+= sun-jdk6-license
ACCEPTABLE_LICENSES+= sun-jre6-license

あとは普通にインストール。

# cd /usr/pkgsrc/lang/sun-jdk6
# make install && make clean clean-depends

ユーザーの追加と設定

ごくプライベートな環境とはいえ、root しかいないってのは精神衛生上よくないので。

# groupadd tkmsaoi
# useradd -g tkmsaoi -G wheel -s /usr/pkg/bin/bash -m tkmsaoi
# passwd tkmsaoi
dotfiles

tkmsaoi/dotfiles · GitHub

$ git clone https://github.com/tkmsaoi/dotfiles.git
$ cd dotfiles
$ ./install.sh
rbenv

ずっと rvm を使ってたんですが、試してみました。
rvm も優れたツールですが、rbenv で必要十分ですね。

その他

普通に使ってる分には気にならないんですが、環境構築の時はさすがに Micro SD の書き込み速度が気になります。
環境構築を終えるまではローカルディスクでやったほうがいいかもしれません。


構築したことに満足して、実はそんなに使ってない。あるある。

1年後。その Micro SD の所在は不明です。

is_callable で true を返す値と呼び出し方法

前の記事の流れで、「どんな値で is_callable が true を返すのか」「is_callable で判定した後 $obj() で呼び出しちゃっていいのか」とか、色々気になったので調べてみた。

PHP: is_callable - Manual

調べてみた結果、注意したいのは、

  • is_callable($obj) が true だからといって $obj() で呼び出せるとは限らない
    • call_user_func($obj) を使う
  • '<クラス名>::<インスタンスメソッド名>' も true になる
    • 呼び出すと E_STRICT が発生する

ってところかな。

以下、調べてみた結果。
PHP 5.3.27, 5.4.17, 5.5.1 で確認しました。

前提

<?php
$fn = function() {};

function hoge() {}

class Foo
{
  public function method() {}
  public static function staticMethod() {}
}
$foo = new Foo();

$obj に代入して色々した結果

$obj is_callable($obj) call_user_func($obj) $obj()
$fn true
'hoge' true
'Foo::method' true ※1 ×
'Foo::staticMethod' true ×
array('Foo', 'method') true ※1 ※1,2
array('Foo', 'staticMethod') true ※2
array($foo, 'method') true ※2
array($foo, 'staticMethod') true ※2

※1: E_STRICT が出る
※2: 5.3.27 では×

ちなみにクラス名、関数名は名前空間に対応してるのと、クラスはトレイトに変えても同じ動きでした。(インスタンスは作れないので、最後の2つは除く)
あと、メソッドの可視性チェックはしてくれます。

PHP で無名関数であることを判定する

メモ。

is_callable ってのがそれかなって思ったんですが、

PHP: is_callable - Manual

これだと関数名の文字列とか array($obj, 'method') みたいな配列も true になるっぽい。

どうやら PHP の無名関数は

PHP: 無名関数 - Manual

無名関数の実装には Closure クラスを使っています。

ってことらしいので、確実に無名関数を判定したい場合は、こうすればいいみたい。(継承を懸念したけど Closure は final なので大丈夫っぽい)

is_object($obj) && $obj instanceof Closure

Doom のソースコードを読んでみる - 環境構築編

なんとなく Doom のソースコードを読んでみようと思い、コンパイルする環境を構築してみたのでメモ。
ただソースを読むだけだとダラダラしちゃいそうだけど、こうやって記事を書けば、多少なり義務感みたいなのが生じるんでないかと。

Doom ってのはあれです。FPS の始祖みたいなやつですね。

f:id:tkmsaoi:20130211233051p:plain

DOOM - Wikipedia

ゲームエンジンのソースが GPL で公開されているという、素敵なゲームです。
もう発売から 20 年近く経ちますが、僕は割と最近はじめました。
色褪せないです。面白いです。

題材とする Doom エンジン

Doom はソースの公開以来、無数の改良エンジンが作られています。
今回はその中でもオリジナルの Doom に忠実と言われる、PrBoom というエンジンを読んでみます。

PrBoom - Project Homepage

環境

OS は Mac OS X Mountain Lion (10.8.2)、パッケージ管理には Homebrew を使ってます。
Snow Leopard でもコンパイルしてみたんですが、トラップがありました。(後述)

事前準備

Autotools

SVN の最新版をコンパイルしたいので Autotools をインストール。

$ brew install libtool autoconf automake

最近の Xcode (Command Line Tools) には含まれてないんですね。

SDL

PrBoom では SDLSDL_mixer、SDL_net を使います。
いずれも Homebrew でインストールできます。

$ brew install sdl sdl_mixer sdl_net

OpenGL

Mac の OpenGLフレームワーク形式になってて、PrBoom のやり方では configure の時にライブラリが見つけられずエラーになります。
今回はホームディレクトリにシンボリックリンクを作るというゴリ押しで対応しました。

$ mkdir -p $HOME/local/lib
$ ln -s /System/Library/Frameworks/OpenGL.framework/Libraries/*.dylib $HOME/local/lib
$ mkdir -p $HOME/local/include/GL
$ ln -s /System/Library/Frameworks/OpenGL.framework/Headers/*.h $HOME/local/include/GL

加えて、コンパイラやらリンカがシンボリックリンクを見つけれるように ~/.bash_profile とかに以下を追記。

export CFLAGS="-I$HOME/local/include"
export LDFLAGS="-L$HOME/local/lib"

SDL を介して OpenGL を使ってるっぽいので、実は OpenGL のチェック自体を削除しても問題無いのかもしれない。

コンパイル

あとはソースをチェックアウトしてコンパイル、インストール。
今回は $HOME/local 以下にインストールしました。

$ svn co http://www.crowproductions.de/repos/prboom/trunk/prboom2 prboom2
$ cd prboom2
$ ./bootstrap
$ ./configure --prefix=$HOME/local
$ make install

エラーが無ければ、$HOME/local 以下に色々できてるはず。

起動してみる

IWAD を ~/.prboom ディレクトリにコピーします。

$ cp path/to/doom.wad ~/.prboom

IWAD ってのは Doom のゲームデータで、Doom はこれとゲームエンジンを組み合わせて遊びます。
僕は製品版の IWAD を持ってるのでそれを使ってますが、Freedoom っていうフリーの IWAD もあります。

あと $HOME/local/games/prboom ってのがゲームエンジン本体なので、~/.bash_profile とかで PATH を追加しときます。

export PATH="$HOME/local/games:$PATH"

そして起動!

$ prboom

f:id:tkmsaoi:20130211233052p:plain

ちゃんと動いとる!音が若干おかしい気もするけど。

ちなみに 16:9 (1366x768) でキャプチャを撮ったら・・・

f:id:tkmsaoi:20130211233102p:plain

何とも前衛的な仕上がりに。バグでしょうか?

まあなんとかコンパイルして動かせる状態になったので、コードを触ったりしながら読んでみようと思います。

番外: Snow Leopard での注意点

現状 (2013/02/11 時点) Homebrew で SDL をインストールすると 1.2.15 ってバージョンがインストールされます。
Snow Leopard でもコンパイルは通るんですが、実行すると・・・

$ ./src/prboom

prboom v2.5.0 (http://prboom.sourceforge.net/)

# 中略...

2013-01-08 01:11:34.257 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x100348b40 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.262 prboom[57133:9007] -[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10
2013-01-08 01:11:34.262 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037b8d0 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.263 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037cba0 of class NSException autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.263 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f7f0 of class _NSCallStackArray autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.264 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f850 of class _NSCallStackArray autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.264 prboom[57133:9007] An uncaught exception was raised
2013-01-08 01:11:34.266 prboom[57133:9007] -[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10
2013-01-08 01:11:34.266 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x10037f9c0 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.267 prboom[57133:9007] *** __NSAutoreleaseNoPool(): Object 0x1008b1200 of class NSCFString autoreleased with no pool in place - just leaking
2013-01-08 01:11:34.268 prboom[57133:9007] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType objectForKey:]: unrecognized selector sent to instance 0x10033fa10'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff89ccd784 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff87a84f03 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff89d27110 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0
    3   CoreFoundation                      0x00007fff89c9f8ef ___forwarding___ + 751
    4   CoreFoundation                      0x00007fff89c9ba38 _CF_forwarding_prep_0 + 232
    5   libSDL-1.2.0.dylib                  0x00000001001e5495 QZ_ThreadFlip + 237
    6   libSDL-1.2.0.dylib                  0x00000001001c4507 SDL_RunThread + 71
    7   libSDL-1.2.0.dylib                  0x00000001001e8eaa RunThread + 9
    8   libSystem.B.dylib                   0x00007fff82b39fd6 _pthread_start + 331
    9   libSystem.B.dylib                   0x00007fff82b39e89 thread_start + 13
)
terminate called after throwing an instance of 'NSException'

派手にエラーが出ます。
どうやら SDL 1.2.15 と Snow Leopard の相性が悪いらしく、フルスクリーンモードで上記のようなエラーが出るようです。
(ちなみに 1.2.15 は Lion のフルスクリーンに対応したバージョンみたいです)

Snow Leopard の場合、一つ前の 1.2.14 を使うのがよさそうです。

$ brew versions sdl
1.2.15   git checkout 4562ce4 /usr/local/Library/Formula/sdl.rb
1.2.14   git checkout af59bb9 /usr/local/Library/Formula/sdl.rb
$ cd /usr/local
$ git checkout af59bb9 /usr/local/Library/Formula/sdl.rb
$ brew install sdl

PHP 用の LTSV パーサを車輪の再発明した

LTSV がアツいらしい。

【今北産業】3分で分かるLTSV業界のまとめ【LTSV】 - naoyaのはてなダイアリー

PHP の実装は既にいくつかあるみたいだけど、PEAR で入れれるのが無いっぽいのと、単純にこの流れに乗ってみたかったので、車輪の再発明してみました。

tkmsaoi/Text_LTSV · GitHub

PEAR からインストールして、

$ pear channel-discover openpear.org
$ pear install openpear/Text_LTSV-1.0.0

以下のように使う。LTSV のパースと生成ができます。

<?php
require_once 'Text/LTSV.php';

$assoc = Text_LTSV::parseLine("hoge:foo\tfuga:bar\tpiyo:baz");
echo $assoc['hoge']; //=> foo
echo $assoc['fuga']; //=> bar
echo $assoc['piyo']; //=> baz

$array = Text_LTSV::parse("hoge:foo\tfuga:bar\npiyo:baz");
echo count($array); //=> 2
echo $array[1]['piyo']; //=> baz

echo Text_LTSV::generateLine(array('hoge' => 'foo', 'fuga' => 'bar', 'piyo' => 'baz'));
//=> hoge:foo\tfuga:bar\tpiyo:baz

echo Text_LTSV::generate(array(
  array('hoge' => 'foo', 'fuga' => 'bar'),
  array('piyo' => 'baz'),
));
//=> hoge:foo\tfuga:bar\npiyo:baz

よければ使ってやってください。

Chrome で背景色や背景画像を印刷する

Chrome は単体で PDF を印刷する機能を持ってて便利なんですが、CSS の background-color や background-image が反映されません。

「背景を印刷」みたいなオプションも見当たらなかったので、無理なんかなーって思ってたんですが、どうやら CSS で解決できるっぽいです。

@media print {
  body {
    -webkit-print-color-adjust: exact;
  }
}

人様のページであっても、デベロッパーツールを使えばなんとかなります。

f:id:tkmsaoi:20120920211457p:plain

-webkit ってベンダープレフィックスが付いてますが、Safari 5 では動きませんでした。
未だに Snow Leopard を使ってるもんで、Safari 6 は確認できてません。

以下、参考にさせてもらいました。

TIP: Print CSS backgrounds in Google Chrome & Safari webkit


おまけ

各ブラウザが「背景を印刷」的なオプションを持ってるのか、気になったのでついでに調べてみました。

IE 9
"ページ設定" → "背景の色とイメージを印刷する"
Firefox 15
"ページ設定" → "背景色と背景画像も印刷"
Opera 12
"印刷オプション" → "背景を印刷する"
Chrome 21
見当たらず
Safari 5 (Windows)
見当たらず (ていうか Windows 版の Safari は終了っていう認識でいいの?)
Safari 5 (Mac)
"プリント" → "プリンタ" の右の下矢印 → "背景をプリント"

設定さえすれば大体どのブラウザでも印刷できるんですね。設定さえすれば。