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

Javascriptで型判定

こんな感じでいかが。

var type_of = function(o){
  if ((t=typeof o)!="object") { return t; }
  if (t===null) { return "null"; }
  return Object.prototype.toString.apply(o).match(/\[object (.*?)\]/)[1];
};

クロスブラウザで同じ結果が得られるかは試せてません。コメント期待…。

Javascriptはtypeof([1,2,3])がobjectなところが香ばしいですね。

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

ruby-debugのちょっとだけ高度な使い方

便利なコマンド

ps

オブジェクトが配列なら、ソートした上でカラム上に並べて見やすくしてくれます。

Using the ps command in ruby-debug

Railsのメソッド一覧をpsしてみた

irb

その場でirbに突入します。後述のautoevalをONにしてればあまり意味はないかも。

Debugger.settingsでオプション設定

require 'ruby-debug'したあとでDebugger.settings[:key]=valueすると各種オプションを設定できます。網羅的なリストはこちら。特に便利なのは以下。

:autoeval

trueにすると、デバッガコマンドが見つからないときは自動的にevalを試してくれます。*** Unknown command: "User.first.name". Try "help".がしばしば出てしまう僕にとっては必須。

ちなみにRailsでは、テストヘルパ(railties/lib/test_help.rb)でautoevalが設定されてます。

:autolist

trueにすると、デバッガに入ったときやステップ実行時などに自動的にlistを実行して周辺コードを表示してくれます。

これもRailsのテストヘルパで設定されてます。

:forcestep

trueにすると、ステップ実行時に必ず別の行へ飛びます。
Rubyは一行で色々書けるので、普通にステップすると同じ行内でステップすることもありますが、このオプションを使えば一行=1ステップになります。

参考:
Debugging with ruby-debug

Categories: Whatnot | Tagged , , | Leave a comment

undefined method `rewrite’ for “…”:String

Railsのコントローラで謎のエラー

NoMethodError (undefined method `rewrite' for "http://colinux/sample/":String):

app/controllers/start_controller.rb:33:in `index'

これはどうやらActionController::Baseな場所で@urlという変数をアサインした上でredirect_toなどすると発生するらしい。わかるかそんなこと!

undefined method `rewrite for #.

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