2007年5月9日水曜日

Day 8: 使用箇所の検索

元記事


31日間ReSharper一周」の8日目にようこそ。


サバイバルガイドで書いたように、ReSharperはVisual Studioの「すべての参照の検索」(Shift+F12)を独自の「使用箇所の検索」(一貫性なくAlt+F7に変えられた)に差し替える。ReSharper版とVisual Studio版がどう違うのか、詳しい情報を記す。


「get」や「set」の使用箇所をフィルタリングする


そこかしこで読み取られるけどごく一部でしか書き込まれないようなプロパティってあるよね。そしたら「すべての参照の検索」でプロパティのセッターだけ探したくならなかった?こうすればいい。


ReSharperの「検索結果」ウインドウ。フィルタメニューを見ると、読み取りまたは書き込みだけを表示する選択肢がある。


フィールドでも同じことができる。あるフィールドが読み取られているところだけ、または書き込まれているところだけを探すことができる(Reflectorにもこの機能があればいいのになあ)。


スクリーンショットを見ればわかるが、「検索結果」ウインドウのフィルタメニューには、「読み取りを表示」と「書き込みを表示」と「呼び出しを表示」と「その他を表示」(どういう意味か分からない)、そして「ドキュメント中の使用箇所を表示」(XMLドキュメントのコメントのことだろうか)という選択肢がある。「その他を表示」はメソッドを参照するデリゲートのことかとも思ったが、明らかにそれらには「読み取りを表示」が使われている。


今後のバージョンでは、プロパティ宣言中の「get」や「set」を右クリックして「使用箇所の検索」を選択すれば、状況に応じて読み取りや書き込みだけが表示されるようになるとのことだ。これは待ち遠しい。


検索結果を前後移動する


「使用箇所の検索」を実行した後でCtrl+Alt+UpとCtrl+Alt+Downを使えば、検索結果を前後移動できる。カーソルが次の検索結果のところに移動し、場合によっては別のファイルが開かれる。端まで移動した後はループしない。最後まで来たことが分かるからある意味便利だ。


「検索結果」ツリー


嫌なところはといえば、「検索結果」ウインドウ内での検索結果の見せ方がどうにも好きになれない。


Visual Studioでは、全部が一覧表示されるだけだった。


Visual Studioの「シンボルの検索結果」ウインドウ


全ての項目にはファイル名と行番号(とカラム番号。気にするかっつーの。)が表示されるから、少なくとも、それぞれの参照がどのクラスにあるのかは分かる。いっぽうReSharperでは、すべてはツリー表示される。


ReSharperの「検索結果」ウインドウ。検索結果は最初は折りたたまれている。


いつも最初はツリーが折りたたまれている。だから検索結果を見るだけじゃすまなくて、最低1回は(すべてを開くために)クリックしないといけない。しかも、ツリー表示をやめて結果をそのまま表示するために、「グループで分類」の設定を「なし」に変えたとする。そしたら検索結果がどのファイルに含まれているのか知ることができなくなる。各行は一致したコード行を表示するだけで、ファイル名や行番号といった情報が表示されなくなってしまう。


(僕はデフォルトで検索結果を展開表示できるように機能改善する要求を出した。回答には、まったく同じことをたくさんの人が要求しているとあった。だからどこかのタイミングで機能改善されるかもしれない。)


とはいえ、ツリーを展開さえすれば、結果がどのクラスに含まれるかだけじゃなくて、どのメソッドにあるのかといった、VSの一覧表示では表示されない情報を見ることができる。

Day 7: コードフォーマット

元記事


31日間ReSharper一周」の7日目にようこそ。


ReSharperは、コードフォーマットについて多くの支援をする。支援方法は大きく3つのカテゴリーに分類される。入力時、ファイル単位での必要時、複数ファイルでの必要時だ。


入力時のフォーマット


こんなの目新しくないよね。Visual Studioだってこの機能はしばらく前から持ってた。でも、ReSharperのフォーマット設定はもちろんバージョン管理できるし共有もできる。だから、型変換の直後にスペースを置くマシンと置かないマシンが混在したりしない。ここだけは勝っている。


ReSharperの他のフォーマット機能で素晴らしい所は、空のカーリーブレースの中でEnterを取り扱う方法だ。Visual Studioでの取り扱いより少しよくて、自動終了デリミタにきちんと関連づいている。















空文で始める。
開始ブレースを入力して...
Enterを押す。

ファイル全体をフォーマットする: Ctrl+Alt+F


ReSharperには、作業中のソースファイル全体を再フォーマットするコマンドもある。Ctrl+Alt+Fを押せば、「コードを再フォーマットする」ダイアログボックスが出る。



注目してほしいのは、この機能は空白文字をいじるより多くのことができるってことだ。コード中の灰色部分を修正させることもできる。「using文を最適化する」とか「冗長な'this.'修飾子を削除する」なんてのは見たまんまだ。「参照を短くする」では、System.Drawing.Graphicsが単にGraphicsに変更され(、usingが足りなければ追加され)る。


僕らはいつも、このチェックボックスの全部にチェックを入れている。コードはできるだけきれいであってほしいからね。ここでの設定は次回にも引き継がれる。


追記: Maruis曰く、Ctrl+Alt+Shift+Fならサイレントモードになり、ダイアログはポップアップしない。しかもちゃんと前回選択した設定を使ってくれる。すばらしい!ありがとうMaruis!


コードを再フォーマットする時に、ReSharperは以下のこともする。



  • 明示的な可視性修飾子を追加する。可視性修飾子のないクラスにはinternalが追加される。可視性修飾子のないフィールドにはprivateが追加される。(これは、ReSharperの他のすべてと同じように、変更可能だ。だから、コードを読みやすくしたくない理由があるのなら、この設定をオフにしたっていい。)

  • 単純なゲッターとデリゲートを一行に置く。もし、ゲッター/セッター/デリゲートの本体が1文なら(例えば、値の付与だけとか、return文だけとか)、ReSharperは閉じカッコもまとめて1文にする。だからReSharperは下のようなひどいフォーマットのコードを見つけて……
    public Color BorderColor {
    get
    {
    return _borderColor;
    }
    set { _borderColor = value; Invalidate(); }
    }

    こんな具合に再フォーマットする。
    public Color BorderColor
    {
    get { return _borderColor; }
    set
    {
    _borderColor = value;
    Invalidate();
    }
    }

    Visual Studio 2005は、ゲッターやセッターが1行なら「折りたたみ」用の+記号を出さないでいてくれるので、この機能は本当にありがたい。


プロジェクトまたはソリューションを再フォーマットする


最後になるけど、ReSharperにはたくさんのファイルをまとめて再フォーマットするオプションがある。フォルダかプロジェクトかソリューションを右クリックして、「コードを再フォーマットする」を選択するだけだ。


言うまでもないことかもしれないが、一応注意しておこう。コードを変更していたのなら、まとめて再フォーマットする前にソース管理リポジトリにコミットするべきだ。ソリューション全体の再フォーマットをするなら、また別途コミットするほうがいい。この機能で変更する場合、やってほしくない変更をしてしまう時だってある。設定を変更するにしろ、予想外の結果を受け入れるにしろ、その前に一部だけ前の状態に戻したいと思うこともあるだろうからね。


あんまりうまくいかないところ #1:デリゲートのインデント


デフォルトでは、ReSharperはインラインのデリゲートをおかしなところにインデントする。これはReSharperのデフォルトが間違ってると思うことの1つだ。コードは普通にインデントしてほしい。コードの半分がこんな風にでこぼこの中央揃えになるのは嫌だ。


Block incrementer = delegate {
++i;
++j;
};
Block resetter = delegate {
i = 0;
j = 0;
};

これを直す方法をやっと見つけた。匿名メソッドのフォーマット設定はReSharperオプションの2つのページに分けられている。「Braces Layout」と「Other」だ。「おかしなインデントはやめろ」は「Other」のページにある「匿名メソッドの本体をインデントする」だ。これをオフにして、カッコの設定を「行の最後に置く」にすれば、ずっとましになる。


Block incrementer = delegate {
++i;
++j;
};
Block resetter = delegate {
i = 0;
j = 0;
}

あんまりうまくいかないところ #2:Xceedのライセンス


ReSharperは修飾子をできる限り短くしようとする。変な状況にはまってしまうと可読性が悪くなることもある。以下がそんな例だ。僕らの回避策(けっこううまくいったと思う)も載せておく。


僕らはXceed社のコンポーネントを使っている。Xceedで何よりイライラするのはライセンスの許諾方法だ。配布されるライセンスキーはアホほど長い英数字で、実行するためには、初期化コードでこの文字列を静的プロパティに突っ込まないといけない。こんな感じだ。


Xceed.Grid.Licenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
Xceed.Editors.Licenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

そう。Xceedのアセンブリごとにライセンスキーをセットしないといけないんだ。そうしないと、実行時に文句を言われることがある(言われないこともあるから意味が分からん。でもとにかくライセンスキーはセットするようにしている。念のためにね)。


変なのは、複数のアセンブリに含まれているLisenceKeyというクラスについてだ。ReSharperはこんな感じで短くしようとする。


using Xceed;
using Xceed.Grid;
...
Licenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
Editors.Licenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

ぎゃぼー。回避策はこんな感じ。こう書けばReSharperはそのままにしておいてくれる。


using GridLicenser = Xceed.Grid.Licenser;
using EditorLicenser = Xceed.Editors.Licenser;
...
GridLicenser.LicenseKey = "LOTS-OF-LETTERS-AND-NUMBERS";
EditorLicenser.LicenseKey = "SOME-OTHER-LETTERS-AND-NUMBERS";

ツールの制限を避けるためではあるけど、こっちの方が読みやすいんじゃないかな。

2007年5月7日月曜日

Day 6: 共有設定は.resharperファイルの中に

元記事


31日間ReSharper一周」の6日目へようこそ。


時々、IDEがマシンごとに違う設定になってることがある。僕らは全員、ブルペン内の全マシンを使うから、時間がたてば相違点は解消されていくんだけど、ムカつくときだってあるわけ。特にコードの自動フォーマット設定は最悪だ。デザイナ画面で何かをちょっと動かすとかいった、一見無関係な変更をしたときでさえファイルが自動的に再フォーマットされてしまう。


頼みの綱はReSharper。いくつかの設定は、ソリューションディレクトリ上のとあるファイルに格納される。それは.resharperファイルだ。だから、.resharperファイルを他のファイル全部と一緒にソースコードリポジトリに突っ込めば、開発チームの誰でも同じ設定を使用することになる。


.resharperファイルに保存されるものには面白いものが2つある: コードフォーマット設定とテンプレートだ。


コードフォーマット設定の共有


ReSharperのオプション画面。コードスタイル設定をバージョン管理システムに保存する際の設定。


上の(ReSharper > Options > Code Styleとたどった)スクリーンショットの通り、ReSharperには、コードフォーマット設定の共有に関して3つの異なる選択肢がある。



  • すべてが現在のユーザー専用。これがデフォルトだ。マシンは1台、開発者は1人ってだけならこれで問題ない。

  • 現在のソリューションをチームで共有。開発者が複数で、Visual Studioのソリューションは1つだけなら、この設定がいい。全員が同じコードフォーマット設定を使う。

  • 現在のソリューションを外部ファイルで設定。これを使うにはもう少しやることがあるけど、(僕たちみたいに)同じソースツリー内に複数のソリューションがあるなら、これを使おう。


最後の設定を使うには、Exportボタンを使って、設定をどこかの.xmlファイルに保存しておかないといけない。それからそのファイルのパスを指定する。同じソースツリーに含まれている複数のソリューションで設定を共有しているのであれば、相対パスを指定したいところだ。


テンプレートの共有


以前は、ソリューションに新しいクラスを追加したときは、そのコードをきれいにするのに数秒はかかっていた――クラスの可視性を修正したり、不要なusing文を削除したり。新しいインタフェースが欲しいときは、「新しいクラスの追加」をやってから「class」キーワードを「interface」に置換していた。たいした手間ではないけど、その手のことは自動化できたっていいじゃないか。コンピュータだもの。


ReSharperでは数種類のコードテンプレートを定義できる。「ライブテンプレート」(Tabキーで移動して値を入力するようなフィールドをもつもの)、「囲む」、そして「ファイルテンプレート」だ。どれも設定を変更でき、変更した設定は全部.resharperファイルに保存される。というわけでもう一度言うけど、開発チームの全員で自動的に共有される。


ReSharperにはサンプルのテンプレートがいくつか含まれているから、中を見て、どういう動きをするのかを知ることができる。ただイラつくのは、そのサンプルだと各ファイルの先頭にコメントブロックがあって「作者」だとか「日時」だといった欄があるんだ――何が楽しくてこんな情報を複製するんだって話だ。ソースコードリポジトリを見れば、誰がファイルを追加したのか一目瞭然だってのに。(たぶんイラつくようにわざと作ってあるんだ。そしたら間違いなく自分用のテンプレートを作る気になるだろうから。僕たちはそうだった。)


独自のテンプレートは簡単に作れるけど、若干ひねくれている。ここが大事なんだけど、「Available everywhere」っていうハイパーリンクはクリックした上で、「いや、C#だけで使う」って指示しないといけない。(そうしないと、ファイル名の拡張子を追加してくれないんで、ファイルが正しくフォーマットされなくなる。) しかも、$NAMESPACE$ みたいな特別なプレースホルダを使いたいなら、名前だけでは認識してくれないので要注意だ。「テンプレート変数」のグリッドの中で「マクロを選ぶ」をクリックして、一覧の中からマクロを選ぶ必要がある。


「テンプレートを編集」ダイアログ内の「Available Everywhere」ハイパーリンク


「テンプレートを編集」ダイアログ内の「テンプレート変数」グリッド


テンプレート内で使えるマクロの一覧

2007年5月6日日曜日

友人のライブと外山恒一

新中野のライブハウスに行ってきた。


帰りに新宿駅で降りたのだが、そのときに外山恒一氏と思しき人を見た。話しかけたりしなかったので本人かどうかは分からないけどね。

ライブはこんな感じ。携帯電話で撮ったから何がなんだか分からないかもしれない。だが、それがいい。



















大木ちゃん?

仮面ライダー電王に大木ちゃんが出てた?
別人かなあ。どうかな。第15話、6分30秒あたりからなんだが……やっぱ違う人かな。

Day 5: 統合されたユニットテストランナー

元記事

31日間ReSharper一周」の5日目へようこそ。今日はReSharperのユニットテストランナーを紹介する。



(ReSharperのユニットテストランナーは無料で別個にダウンロードすることもできる。もし完全なReSharperが不要ならばね。)


しかし、なぜ世界に更なるユニットテストランナーが必要だったのか?テストを実行する方法はすでにたくさんあるわけだし。NUnit GUIもあるし、NUnitコンソールランナーもある。MSBuildでソリューションをビルドした後NUnitコンソールを実行するようなrakefileを書いて、そのファイルを呼び出すようにツールメニューのオプションを設定して、それに対してキーストロークを割り当てることもできる(僕はそうしている)。TestDriven.NETをインストールしてもいい。(Microsoft謹製テストランナーに大枚をはたいたっていい。実際にはテストを実行させてくれないとしても。)これで選択肢は全部カバーできてない?


そうかもしれない。でも、ReSharperのテストランナーはピカイチだ。IDEのアドインだから、うまく統合されている。では見ていこう。


テストを全部実行する


前にもぶーたれたことがあることだし、テストツールのいっちばん基本的な機能から始めよう。全テストの実行だ。


もちろんReSharperでできるし、それに簡単だ。全テストを実行する一番よい方法は、ReSharperAddIn25.UnitTestRunner_RunAllSolutionコマンドにキーストロークを割り当てることだ(僕らはCtrl+Shift+Tにしてる)。そうすれば、Ctrl+Shift+Tを叩けばいつでも、自動的にソリューションがビルドされ、全テストが実行され、結果に応じて緑(または赤)のバーが表示される。


もしそこまで簡単にしたくないのなら、ReSharperメニュー > Unit Testing > Run All Tests from Solution を実行するのでもいい。Unit Testingメニューにはあと2つほど別のオプションがあるけど、僕は無視してる。全テストを実行する以外のことをするように見えるからだ――今のところ、NUnitのテストをすばやく実行することでかなりうまくやれている。


対応しているテストランナー


追加設定なしで、ReSharperのテストランナーはNUnitcsUnitのテストに対応してる。ReSharperのUnitRunをmbUnitに対応させるサードパーティのアドインもある。


統合


ReSharperのテストランナーアドインはVisual Studioの中にいることを本当にフル活用する。



  • ドッキング可能。テストランナーのウィンドウはIDEの他のウィンドウとまったく同じようにドッキング可能だから、邪魔にならないところに押し込んでおくこともできる。僕はIDEの一番下のところの、「出力」ウィンドウや各種「検索結果」ウィンドウのタブにくっつけている。(タブの中に置いておいたとして、テスト実行時にもし別のタブが表示されていたら、テストランナーのウィンドウが前面にくる。期待通りにね。)

  • キー割り当て可能。上でも書いたが、1キーストロークが「全部ビルドして、全部テストして、結果を赤や緑のバーで表示する」に割り当てられているのは超楽。マジで楽。

  • 注意を払う。コードを変更してリビルドすると、テストツリーの全アイコンが小さいクエスチョンマークに変わるから、まだテストされていないことが見てわかる。でも色はそのままだから、前回はどれが成功でどれが失敗だったかも見ればわかる。以下は「最新の実行」(チェックマーク)と「リビルド後」(クエスチョンマーク)のスクリーンショットだ。

    さらに賢いのは、ソリューションをビルドしたときに、実際にはコードを何もいじっていなかったなら、クエスチョンマークにはならないんだ。(この機能はありがたい。なにしろ、しゃべったりなんかするとすぐ気が散って、テストを実行したかどうかも覚えてられないからだ。)

  • コードへジャンプ。これには素晴らしい機能が2つある。1つ目。テストツリー上のテストをダブルクリックすれば、そのテストのコードがエディタに表示される。2つ目。テストが失敗したら、テスト結果ペインの呼び出しスタック中にハイパーリンクが出力され、そのうちの1つをクリックすればエディタでその場所へジャンプする。

  • テストを走らせたりデバッグしたりするガター(左余白)アイコン。テストメソッドを発見すると、ReSharperはコードの隣のガターに緑と黄色の小さい円を表示する。その円をクリックするとドロップダウンメニューが表示される。メニューの中にはそのテストをデバッガで実行するオプションがある。だからテスト中にブレークポイントを設定してデバッグしたいなら簡単にできる。


実のところ、ReSharperのユニットテストランナーの機能には別段革新的なものはない。「コードにジャンプする」機能はかなりすばらしいけどね。要は、機能が全部そろっていて、どれもちゃんと使えるってだけだ。ユニットテストをするんなら、ReSharperのテストランナーを試してみるといい。

2007年5月3日木曜日

ワンス・オブ・センダー

ナハッ


えーと、仕事してないときはこういうことばっかり考えています。

2007年5月1日火曜日

MS主催のWeb系カンファレンス "MIX '07"

http://visitmix.com/
現地時間の4月30日~5月2日開催。現地では初日は終わったかな。
以下メモ、随時更新。

関連して

Day 4: 自動閉じデリミタ

元記事

31日間ReSharper一周」の4日目へようこそ。


タイプし始めるとすぐ気付く機能がある。開始デリミタを入力すると、ReSharperが終了デリミタを入力してくれるんだ。


単純な機能だけど、ちゃんとやるのはそれほど単純じゃないし、2.5から紛れ込んだバグ(その後2.5.1では修正されたけど)を除けば、ちゃんとやれている。おかしなことをすることはめったにない。


この機能は次のデリミタで動作する; { 、( 、[ 、" 、そして ' だ。ただしジェネリクスの文法は自動補完してくれない。< は対象外なんだ。


動作サンプルは以下だ。















































最初は空文。
メソッド名を入力して……
「(」を入力する。
部分式を入力して……
「(」を入力する。
おっと、「(」じゃなくて「[」だった。Backspace……
「[」を入力する。
パラメータを入力し終わったら……
「]」を入力して……
「)」を入力して……
「;」を入力する。

正しくやるべきときに正しくやってくれている。開始デリミタの直後でバックスペースを押せば、(カッコの中で何も入力してなかったなら)終了デリミタも消してくれる。しかも、カーソルが終了デリミタの直前にあるときに終了デリミタを入力しても、終了デリミタは2つにならない。この動作はセミコロンでも同様だ; カーソルがセミコロンの前にある時にセミコロンを押したって、セミコロンが2つになることはない。しょっちゅう右矢印を押したりせず、いつもどおりに入力できる。


この機能は賢いので任意のネスト内でもちゃんと動く。もし開始デリミタを入力したときに終了デリミタがすでにあるなら、終了デリミタは追加されない。当てずっぽうの時だってあるに違いないと思うんだが、気付くような間違いが起きたことなんてなかったように思う。


注意: {を入力したときには対応する}が自動的に入力される――つまり、中カッコでコードブロックを囲もうとしていたとしても、対応するデリミタはカーソル直後に入力されてしまうということ。その代わり、現在の選択範囲を中カッコで囲みたいときには「囲む」コマンドを使うといい。ショートカットはCtrl+Alt+J、8だ (Ctrl+Alt+Jでメニューがポップアップ表示されるから、8のとこは覚えなくていい)。


(追記: ReSharper開発者のIlyaが指摘してくれたんだけど、ReSharperでは、{キーの直後ではなく、Enterキーを押したときに閉じカッコを追加するようにできるから、既存コードブロックを中カッコで囲むのがやりやすくなるだろうって。Ilyaありがとう!)

ベーコンほうれん草スパゲティ

にんにくと厚切りベーコンをオリーブオイルで炒め、ほうれん草とカルピスバターを足し、醤油で風味づけ。スパゲティは早めに茹で上げ、茹で汁(お玉で1~2すくい)を入れ、乳化したら麺にからめて熱いうちに食べる。


よく作るスパゲティだけどいつもより美味かった。