CygwinをPuTTYクローンと一緒に使えば思ったほど悪くない

Cygwinは最初に入れたときの見た目の印象があまりにも悪すぎてずっと敬遠してきたんですが、改めて導入してみると意外と使える事に気づきました。

Windows環境でgitを使うのが一番の目的で、他の選択肢としては TortoiseGit
msysgitのgit bashなどがあるんですが、それぞれにデメリットがあります。

  • TortoiseGit
    • 通常使用に堪えるクオリティになってるけど、中で何が起こってるのかよく分からないのでgitを使いこなしてる感がない
  • msysgitのgit bash
    • ベースがコマンドプロンプトなので使いにくい。
    • フォント変えられない。横幅広がらない。
  • VMWare経由
    • さあコミットしようという時にサスペンドされてたりしてちょっと面倒

というわけでCygwin再挑戦の記録。実にNot bad at allな環境ができあがりました。さようならコマンドプロンプト。

成果

  • FuTTYっていう高機能でポータブルなPuTTYクローンを使えてる
  • Puttyから256色ターミナルでscreen+zshできてる
  • screenをマウスでスクロールできてる
  • screen中にPuttyをいきなり閉じて再接続したらアタッチできてる
  • vim file.txtってするとWindows側のgvimが起動してくれてる
  • 日本語の読み書きもバッチリ
  • もちろんgitもバッチリ

導入1:Cygwin

http://cygwin.com/install.html からダウンロードしてインストールするだけです。最初にインストールしておくパッケージは好みの問題ですが僕の場合はこんな感じです。

  • zsh
  • git-core
  • git-svn
  • wget
  • make
  • gcc
  • openssh
  • vim (gvimがあるなら入れなくていい。後述)

導入2:FuTTY

“cygwin putty”でググルと「cygtermとPuTTYごった煮版を使え」という内容ばかり出てきますが、不要です。cygtermのビルドも、ややこしい環境変数設定も不要です。PuTTYもごった煮版ではなく高機能な海外産のPuTTYクローンを使いましょう。最近のCygwinは内部文字コード変換によってUTF-8をサポートしているみたいなので、日本語パッチなしのPuTTYでも問題なく日本語が扱えます。

ちょっと探してみるとPuTTYクローンは色々見つかりましたが、最終的に落ち着いたのはFuTTYです。これの特徴は色んなPuTTYクローンのいいとこ取りで、

  • PuTTY Trayのトレイ収納機能
  • ファイルに設定を保存するポータブルモード
  • 切断されたホストへの再接続機能
  • PuTTYCygのCygwin接続機能
  • フルスクリーン表示
  • 透過
  • URLを自動リンク
  • マウス中ボタンで貼りつけ、右クリックでメニュー

などなど、素敵な機能が揃ってます。UIは英語ですが。

導入はダウンロードして実行するだけ。Cygwinに接続するためにはcthelper.exeというプログラムが必要ですので同じ場所から落としてFuTTY.exeと同じ場所に置きます。 なおPageantなどは付属してないので必要ならばPuTTYの公式サイトからどうぞ。

導入3:FuTTYからCygwinへ接続

この状態ですでにFuTTYからCygwinへ接続できるはずです。FuTTYを起動し、

  • Connection TypeはCygtermを選択
  • 普段ホスト名を入れるところに-と入力
  • Window->Translation->Character Set TranslationでUTF-8
  • Connection->Data->Terminal-type stringにxterm-256color

そしてOpen。

ででーん。

ホスト名の欄にzshなどと書けば最初にzshが起動してくれます。僕はここにscreen -Rを入れて、.screenrcでshell /bin/zshと設定してます。

なお、設定を保存するときにSessions from fileを選んでおけばレジストリに書き込まずファイルで設定を管理してくれます。Cygwinと一緒にUSBで持ち歩けてしまう。Dropboxにまるごと入れとくのもいいかも。

設定1:日本語

PuTTYの文字セットをUTF-8に設定します。.bashrcなり.zshrcなりで

export LC_LANG=en_US.UTF8

設定2:screen関連

マウスホイールでスクロールバックできるように。これはFuTTYの接続設定にてTerminal->Features->Disable switching to alternate terminal screenをチェック。仕組みはよく分かってません。

ちなみにアタッチ・デタッチはautodetachオプションがデフォルトでオンなので特に何もせずとも利用できます。

256色対応するには.screenrcに

term xterm-256color
defbce "on"

を追記すればOKなはず。

設定3:Windows側のvimを起動させる

これはめちゃ便利です。すごい。Cygwin内から外のgvimを使う – ぱせらんメモにあるスクリプトを使えばvim file.txtとしたときにWindowsのgvimが起動してくれます。 Cygwinの/binなどにvimという名前で置いて実行権限を与えときましょう(chmod a+x vim)。

二個目のファイルを開いたときに同じウィンドウの新タブで開くよう改変したものを貼っておきます。

#!/bin/bash

# gvimのパス
WINDOWS_GVIM=/cygdrive/c/programs/dev/vim/vim73/gvim
# HOMEを削除
unset HOME
# vim起動時のコマンドラインオプション
moreargs=--remote-tab-silent

if [ $# -eq 0 ]; then
  $WINDOWS_GVIM &
else
  args=()
  for arg in "$@"
  do
    # 実在するファイルか"-", "+"で始まらなければcygpathに通す
    if [ -e "$arg" -o \( ${arg:0:1} != "-" -a ${arg:0:1} != "+" \) ]; then
      args=("${args[@]}" "$(cygpath -wa "$arg")")
    else
      args=("${args[@]}" "$arg")
    fi
  done

  $WINDOWS_GVIM $moreargs "${args[@]}" &
fi

改行コードをUnix (\n)にしておかないと正しく実行できないかも。

まとめ

  • Cygwin意外とやるやん
  • PuTTYはすごいけどFuTTYはもっとすごい
  • 見た目がきれいだと使いやすい
  • 忘れてたけどgitもちゃんと使えてる

普段EUC-JPなホストにつないで作業しないといけない人はFuTTYの導入に躊躇するかもしれませんね。一応、PuTTYjpのパッチをFuTTYに導入してくれないかとお願いのメールを送っておきました。果たして対応してもらえるかな?

おまけ:その他のPuTTYクローン

PuTTYCygに対応してるものも多い。

Categories: HowTo's, Tips and Tricks |Tagged , , , , , , , | Leave a comment

Windowsからログオフ時にVMWareをサスペンドする

バーチャルマシンが走ってる時にうっかり再起動してしまってVMが強制終了されることがよくあります。でもいちいちサスペンドするのは面倒なので、ログオフ時に自動的にVMをサスペンドしましょう。

やることは二つです。

VMをサスペンドするスクリプトを書く

バッチファイルを以下のように作成します。

"C:\Path\To\VMWare\vmrun.exe" suspend "C:\Path\To\machine.vmx"

そのスクリプトをログオフ時に実行させる

Win+Rで「ファイル名を指定して実行」を開き、gpedit.mscを実行します。なにやらMSらしい窓が開くので、ユーザの構成>Windowsの設定>スクリプト>ログオフを開きます。

追加を押して、さっきのバッチファイルを指定すればOK。

Categories: HowTo's, Tips and Tricks |Tagged , | Leave a comment

Objective-Cのretain/releaseことはじめ

iOSでの開発をするために最低限知っておくべきメモリ管理法です。

iOSにはガベージコレクションがありませんね。僕はJava/PHP/Ruby出身でGCに甘やかされてきたので、オブジェクトの開放を意識しながらプログラミングしたのは今回が初めてでした。

iOS Reference Libraryのメモリ管理ドキュメントをさらっと読むと、「とにかく自分でretainしたオブジェクトは自分でreleaseしてね」という感じのことが書かれていますが、ちょっとそれだけではうまくいかないシーンが出てきます。

まず、releaseすべきなのはどういうオブジェクトかですが、これは単純です。

  • alloc、new、またはcopyが名前に含まれるメソッドを呼んで手に入れたオブジェクト
  • retainしたオブジェクト

それ以外の場合はreleaseする必要はありません。たとえば

// init系メソッドから入手したのでreleaseすべき
NSArray *pets = [[NSArray alloc] initWithObjects:@"iguana", @"prairie dog", nil];
// initでもnewでもcopyでもないし、retainもしていないので、releaseしなくてよい
NSArray *morePets = [NSArray arrayWithObjects:@"christmas beetle", @"chimp", nil];

releaseしなくてもよいってのは、正確には「releaseしてはいけない」ですね。自分が所持してないオブジェクトをreleaseすると参照カウントが想定より早く0に達してしまい、EXC_BAD_ACCESSの原因になります。

では逆にどういう時はreleaseしても大丈夫なのかという疑問が出てきます。特に、別のクラスのメソッドにオブジェクトを渡した直後にreleaseしてしまって大丈夫なのか?答えは「リファレンスを見ろ」です。メソッドによって扱いが違います。

例えばNSArrayのaddObject:メソッドは、渡されたオブジェクトをretainします。したがって渡したあとでreleaseしてしまって構いません。他にもUIViewのaddSubviewなども渡されたオブジェクトをretainしはります。反対に、同じくNSArrayのindexOfObject:メソッドは渡されたオブジェクトをretainしません。どのメソッドがretainしてどのメソッドがしないのかは、なんとなく雰囲気で分かりますね。

Categories: Whatnot |Tagged , , | Leave a comment

TortoiseSVNのオーバーレイアイコンが更新されない時

TortoiseSVNで、コミットしたのに赤ビックリが消えなくて気持ち悪い時は

  1. F5を押してみる
  2. TortoiseSVN\bin\TortoiseProc.exe /command:rebuildcacheを実行
  3. それでも駄目ならワーキングコピーでCleanupを実行

それでも治らないことがあるようですが。
3番目はワーキングコピーが大きいとちょっと時間がかかります。

参考:
TortoiseSVNのアイコンオーバレイがおかしくなった時 – RX-7乗りの適当な日々
The overlays show the wrong status | TortoiseSVN

Categories: HowTo's, Tips and Tricks |Tagged | Leave a comment

クロージャとはenclosure、つまり同封である

結論:
クロージャは、ClosureというよりEnclosureである。
クロージャとは、あるスコープに同封された別のスコープのことである。
クロージャとは、そういう同封を使った関数のことである。
クロージャとは、そうやって同封された変数のことである。


他の言語にも言える内容かもしれませんが、今回はJavascriptの話です。

「クロージャ」でぐぐると、いろんな曖昧な説明が出てきてどうもはっきりしません。クロージャという言葉が具体的に何を指すのかをはっきり理解しておきたいです。

まず多いのは、「こういう形式の関数がクロージャです」という説明。

var foo = function(){
  var count = 0;
  return function(){
    return count++;
  };
}; // foo()を実行すると、内側の関数が返ってくる
// 返って来た関数を実行すると、countがひとつずつ増える

えっ、どれ?

関数を返す関数がクロージャですか?それとも関数から返されるのがクロージャ?それとも外部スコープの変数を使う関数がクロージャ?

他にも、「関数がreturnしたあとにも生存するローカル変数」とか、「関数定義時の環境を参照できるようなデータ構造」とかいろんな説明が見つかる。なんとWikipediaを見てみると、「(略)な関数のことである」「関数とそれを評価する環境のペアである」「環境に紐付けられたデータ構造のことを言う場合もある」と書いてあります。えらいこっちゃで。

closureを辞書で引かずに浮気する

closureを辞書で引いても「閉じていること」「閉包」「最終的な心の整理」などと言われてイマイチよく分かりません。そこでclosureはenclosureの略だということにして、そっちを調べてみました。

  • Enclosure: 同封物、封入されたもの

うわー!それだー!

スコープその1が同封されている

さっきのコードをもう一度。

var foo = function(){
  var count = 0; // ここがスコープその1
  return function(){
    return count++; // ここがスコープその2
  };
}; // foo()を実行すると、内側の関数が返ってくる
// 返って来た関数を実行すると、countがひとつずつ増える

var counter = foo();
counter(); // => 0
counter(); // => 1

2つのスコープがありますね。2つのスコープを気にしながら、9行目からの実行の流れを追ってみます。

  • foo()を実行した
  • [2行目] スコープその1においてcountは0になった
  • [3行目] スコープその1において無名関数が定義された
  • [3行目] スコープその1で作成された無名関数が返された(スコープその1サヨウナラ)
  • [9行目] counterがその無名関数を参照するようになった
  • [10行目] counter()を実行した
  • [4行目] スコープその2においてcountがインクリメントされた

スコープその2のはずなのに、スコープその1のcountに手が届いています。スコープその1自体はもはや通り過ぎたのに、です。スコープその1が、スコープその2に封入されています!

重要なのでもう一度言います。
foo()から返ってきた関数には、スコープその1が同封されています!
これがEnclosure, 略してclosure!

結論

クロージャとは、まず第一にスコープが同封されていることを言うと考えればわかりやすいでしょう。その上で、Wikipediaに書いてある通り、そういう同封を使った関数や、同封されたスコープや、同封された変数のこともクロージャと呼ぶことがあると考えれば良いと思います。


ちなみに、スコープその2が同封された先は本当はスコープその2ではなく無名関数です。他にも理論的に正確ではないことを言ってる可能性があるので注意してください。

Categories: HowTo's, Tips and Tricks |Tagged , | Leave a comment