2007年7月10日火曜日

Day 26: シグネチャの変更

元記事


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


3つの関数が同じ引数を持つんだけど、それぞれ順序が違う、なんてことが今までにあった?もしあったなら、「シグネチャの変更」はぴったりの機能だ。



ReSharperの「シグネチャの変更」ダイアログは、メソッドのシグネチャに関するどんなものでも変えることができる。ReSharperの他の機能にもメソッドのシグネチャを特定の手段で変更するものはある。たとえば「パラメータの導入」とか。でもこれにはショートカットが無い。以下のことができる。



  • メソッドのリネーム。「メソッドをオーバーロードして委譲」を選んだら、前の名前のメソッドを挿入するが、それは単に新しいメソッドを呼び出すだけしかしない。もしかしたらまだ使うかもしれないから。

  • 戻り値の型を変更。

  • パラメータの追加。デフォルト値を指定する必要があり、その値がすべての呼び出し元から渡されるようになる。でも固定値を毎回渡したくないときだってあるだろう。その場合は次の章を見ること。

  • パラメータの削除。ReSharperはパラメータが使われていないかどうか確認しないから、コンパイルできないコードになってしまうかもしれまない。(パラメータを安全に削除する機能もある。他のとあわせてDay 31で扱おうと思って残してある。)

  • パラメータ名のリネーム。残念、ReSharperはここでは変数名の提案をしてくれない。Ctrl+Spaceを押したとしてもね。

  • パラメータの並べ替え。


どの場合でも、ReSharperは全部の呼び出し元をちゃんと更新してくれる。


新しいパラメータに非固定の値を


新しいパラメータを追加するとき、コードをコンパイル可能に保つために、ReSharperはすでにこのメソッドを呼んでいるすべての呼び出し元を修正する必要がある。つまり、何かを渡す必要があるということだ。これは必須フィールドであり、すべての呼び出し元から渡される何かを指定しないといけない。


じゃあ、すべての呼び出し元からまったく同じ値を渡すのが嫌なら、どうすればいい?それにはいくつか選択肢がある。



  • 「シグネチャの変更」を使わないこと。その代わりに手でパラメータを追加する。そうすればコンパイラが全ての呼び出し元に移動させてくれるだろう――たぶんね(他にもオーバーロードがあると分かって痛い目にあったことがある)。ごく単純な場合以外推奨はできない。だからこういうツールが必要になるんだけど。

  • とりあえずデフォルト値を使い、忘れずに戻って変更すること。これもお勧めはできない。人の記憶力ってそんなにいいもんじゃない。だからそもそもReSharperを使っているんだし。nullのようなデフォルト値は、それを渡すことが一番理にかなったときだけ使うべきだ。

  • どの呼び出し元にも存在しない、asdfjklみたいな意味の無い式を使うこと。ReSharperは止めたりしないけど、(当然)コンパイルできないコードになる。これが実際に役立つのは次のような点だ――コンパイラはすべての呼び出し元に確実に移動させてくれるので、そこで何を渡すべきなのか、ケースバイケースの判断をすることができる。

  • ほとんどの場所で機能すると思われる式を使うこと。もしFooオブジェクトを渡しているのならデフォルト値としてFooとだけ入力してもいい。ほとんどの呼び出し元にはFooプロパティを持ったクラスがいくつかあることを期待してね。僕らはこの手でうまくいったことも多かった。

  • 代わりに「パラメータの導入」を使うこと。もし「パラメータの導入」を使えるのなら、そっちの方が「シグネチャの変更」よりいい。「パラメータの導入」は正しいことを為してくれるからだ。ただし、新しいパラメータをメソッドが知っている形で表すことができるときしか機能しない。

2007年7月8日日曜日

「数学ガール」読んだ

楽しんだ。次は紙と鉛筆を持って、読みながら気づいたわき道を歩いてみよう。


以下は数学にあまり関係ないメモ。



  • カバー裏。(追記)恋の冪級数。
    math girl

  • 「がくら」=学生ラウンジ

惣菜つくった

20070707 惣菜


5品全部俺。

おすすめ


Amazon.co.jpで以前に、Gregor Hohpeの著書をチェックされたお客様に、David Thomasの『Tell Me Why, Mummy』のご案内をお送りしています。



ちょ、別人ww

2007年7月7日土曜日

Day 25: パラメータの導入

モチベーション低下中……


元記事


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


導入系リファクタリングは3つのうち2つ話した(「変数の導入」と「フィールドの導入」)。今日は3番目、「パラメータの導入」。



「型」コンボボックスのてっぺんのピクセルが欠けてたり、「定数の導入」チェックボックスが無かったりするのを無視すれば、かなり「変数の導入」とそっくりだ。動きもほとんど同じ。青いハイライトは邪魔だったり、そんな感じ。


代わり映えしないように聞こえるだろうけど言う。これは効く。びっくりするぐらい賢い。


以下はつまらない例だ。


_tilesWide = GetTilesWide(_previewer);
...
private int GetTilesWide(Control control)

return (control.Width + TileWidth - 1) / TileWidth;
}

この関数に対するユニットテストを書きたいが、テスト内でControlのインスタンスを作りたくはないとする。単にcontrol.Widthをハイライトし、「パラメータの導入」ができた。


おかしなことに、最初に提案されるパラメータ名は、ありそうなwidthじゃなく、iだ(widthはコンボボックスをドロップダウンすれば使えるけど)。controlWidthを提案してくれないのはちょっとサムい。


変数名としてcontrolWidthを入力したとすれば、結果のコードは以下のようになる。


_tilesWide = GetTilesWide(_previewer, _previewer.Width);
...
private int GetTilesWide(Control control, int controlWidth)
{
return (controlWidth + TileWidth - 1) / TileWidth;
}

そうすると、controlパラメータが灰色になる。もう使ってないからね。なので、カーソルをそこに動かしてAlt+Enterを押し、未使用のパラメータを削除できる。するとコードから恐ろしい依存性が消え、よりユニットテストがやりやすくなる。


_tilesWide = GetTilesWide(_previewer.Width);
...
private int GetTilesWide(int controlWidth)
{
return (controlWidth + TileWidth - 1) / TileWidth;
}

(メソッドがpublicだったならパラメータは灰色で表示されなかっただろう。ReSharperは臆病だからpublicメソッドを見てくれないんだ。個々の警告を抑制する#pragmaがサポートされるようになればこれは直るかもしれない。その機能は次のリリースに含まれているそうだ。でもあきらめないように。ReSharperにはパラメータを削除する方法を知っている別の機能もある。)


パラメータを追加することがすごいわけではない。実際、局所変数を追加するのよりすごいことは何もない。すごいのは、呼び出し元に対して自動的に「正しいことを為す(Do The Right Thing)」ことだ。もし呼び出し元に、Conotrolインスタンスを返すようなあいまいで複雑な式を渡すようなものがあったとしても、結果は素晴らしい。あいまいで複雑な式の末尾には.Widthが追加されるだろう。


もっと複雑な式を抽出していてもうまくいく。他のパラメータだけでなくスタティックメソッドも使えるし、現在のクラスが持つインスタンスメソッドやプロパティであったとしても問題ない。ReSharperはちゃんと正しいことを為すだろう。


もう少し現実に近い例を挙げよう。コード中で実際にやるようなことに近いかもしれないし、近くないかもしれない。でもこの記事の残りの部分がフィクションだとしても、すごさが減るわけではない。


processor.ProcessFile(FileType.Foo);
...
public void ProcessFile(FileType fileType)
{
string fileName = this.Configuration.GetFileName(fileType);
...
}

僕らはConfigurationプロパティを取り除こうとしていた。テストハーネス内で何かをインスタンス化するのは怖いし大変だからだ。だからまずはthis.Configurationをパラメータとして抽出するところから始めた。


processor.ProcessFile(FileType.Foo, processor.Configuration);
...
public void ProcessFile(FileType fileType, Configuration configuration)
{
string fileName = configuration.GetFileName(fileType);
...
}

僕が本当にうなってしまったのは(君からすれば単純なことかもしれないが、僕は昔パーサーを書いてみたことがあるから、この手のことは評価するんだ)、呼び出し元に対してちゃんと正しいことを為したことだ。呼び出し元はprocessor.Configurationを渡している。追加したパラメータは、自動的に正しいオブジェクトの正しいインスタンスを使って渡されている。


いやー、すごい。

2007年7月6日金曜日

Day 24: フィールドの導入

元記事

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


昨日はReSharperの「変数の導入」リファクタリングについて話した。今日は「フィールドの導入」だ。


フィールドの追加は変数の追加にかなり似ているが、オプションが追加されている。



ここでは通常の変数名提案(ReSharper Optionsで指定した命名規約に従うもの)が動作する。


「局所変数の導入」と同じく、これも「式を全て置換する」チェックボックスを持ってる。ただ「フィールドの導入」はクラス全体に影響するから、青いハイライトやカラーバーの青い縞は式がいくつ置換されるのかを見る上でもっと便利になった(まあそれらが消えないっていう事実には相変わらず腹立つけど)。


「キャンセル」が文字通りの「キャンセル」ではなく「すべてハイライトさせる」として使われてるというまぬけなふるまいは「フィールドの導入」にもある。本当の「キャンセル」をしたければ、「キャンセル」をクリックした後にEscを押さないといけない(そしてもし本当の「OK」をしたければ、「OK」をクリックした後にEscを押さないといけない。ぎゃぼー)。


基本設定については特に言うことはない。オプションは見るだけでよく分かる。


テストコードを書くには


もしテストコードを書くなら、「××内で初期化する」系のオプションはテストクラスでは1つも使わないほうがましだと気づくはずだ。「現在のメンバー」が便利な時もあるかもしれないが、期待するようなものではないことが普通だ。(私見だが、「コンストラクタ」や「フィールド宣言」は、[TestFixture]付きクラスを書いているときには使用可能にするべきですらないと思う。テスト間の依存性をむざむざ与えてしまうことになる。)


「[SetUp]メソッド内で初期化」を付け加えるように、ReSharperに機能要求を送ったんだが、プラグインとして実装できるからと言われ、「修正しません」としてクローズされてしまった。もしそれが正しいなら、ReSharperプラグインAPIのドキュメント化を続行するという長い道のりを歩き出しているってことになるぞ。だってリファクタリングのサンプルなんてひとつも無いわけだから。書く予定があるとはビタイチ見えない。リファクタリングについては1節だってない。そういうことだから、もし誰かが、既存のダイアログボックスにラジオボタンの選択肢を追加して、その新しい選択肢は既存のリファクタリングの動作を変更するために使う、そんなReSharperプラグインを書こうと思っているならば、最大級の幸運が今すぐ訪れますようにと祈るだけだ。


これで世界の終わりってわけじゃない。「フィールドの導入」はそれでも適切に使える。ReSharperのほとんどの部分ほど良くは無い。手でSetUpメソッドのところまでスクロールしたりとか、そういったことをしないといけない。(にっこり)


もしテストクラスで「フィールドの導入」を使いたいのなら、うまくいくようにする方法は次の通りだ。もしもプラグイン用ドキュメント作成が回避されるんでなければ、それまではね。



  1. 「フィールドの導入」を使い、「現在のメンバー」を選ぶ。

  2. ReSharperが今生成した割り当て命令をカットして、[SetUp]メソッドにペーストする。


実際はそんなに大変じゃない。ただいらいらするだけだ。全てがとても簡単になったのに慣れてしまった。だから、いつもやってることを取り上げられて、簡単にするべきなのにきっぱり断られたりすると、がっくりする。

筋少×すかんち

行ってきた@C.C.レモンホール。メンバーはミウラ&愛理夫妻、ボビナ先輩、おれ。ミウラとボビナ先輩とおれは大学時代に筋少のコピーバンドをやっていた仲。



先陣はすかんち。


実はすかんちはそんなに知らなかった(恋のマジックポーションと恋のミラクルサマーだけだ。ごっつ世代)ので、事前にYouTubeなどで何曲か聴いておいた。改めて聴いてみたら結構面白いね。元ネタ探すのも楽しい。『恋するマリールー』はQueenの"Now I'm Here"とT-Rexの"Get It On"かな。『ウルトラロケットマン』はリフに聞き覚えがあるが思い出せない。全体的にZep風。Black Dogも。曲はExteremeっぽくもある。他に『恋の$1,000,000マン』も聴いた。どうやら定番曲のようだ。今回のステージでも演るかな?



すかんち セットリスト


  1. 恋のミラクルサマー

  2. タイムマシーンでいこう

  3. ラブレターの悲劇

  4. フローラ

  5. 恋人はアンドロイド(Vo. Dr.田中)

  6. 好き好きダーリン(Vo. Shima-chang)

  7. 伝説のスカンチンロールショウ

  8. 恋の$1,000,000マン

  9. 恋のマジックポーション



Rollyはギターも巧いが、歌も上手い。何より声がいい!オーケンとは比べるべくもない。


Keyboardは、前任のDr.田中と後任の小川文明が両方とも参加してた。Dr.田中はキャラ濃すぎ!小川文明はキーボード積みすぎ!


YouTubeで予習した曲は演奏しなかったが、大満足だった。



ステージを入れ替えて、筋肉少女帯の時間。


ギターアンプが2セット準備されたのを見て苦笑。橘高アンプはマーシャルを壁のようにスタックしていたが、おいちゃんのアンプはちんまりしていたからだ。


今回、というか再結成筋少の見所はなんといってもエディと橘高のカラミだろう。その二人による『サンフランシスコ』を楽しみに来たようなもんだ。



筋肉少女帯 セットリスト


  1. イワンのばか

  2. 仲直りの歌(ブースカver)

  3. 仲直りの歌

  4. 踊るダメ人間

  5. 君よ!俺で変われ!

  6. 神菜、頭を良くしてあげよう

  7. 日本印度化計画

  8. 戦え!何を!人生を!

  9. サンフランシスコ

  10. モーレツア太郎



『イワンのばか』から客は大興奮!やっぱりすかんちファンより筋少ファンの方が多かったみたいだ。


オーケンがブースカ人形を使って新曲『仲直りの歌』を披露するくだりはいかにもオーケンらしいグダグダ感。続く『ダメ人間』ではダメジャンプ(Xジャンプ的なもの)でぴょんぴょん。


そしてニューアルバムのタイトル発表!タイトルは『新人』……苦笑する客席。へこむオーケン。そりゃ誰だってネタだと思うだろう。


嬉しかったのは『戦え!何を!人生を!』から『サンフランシスコ』の流れ。いやー来てよかった。そして最後は『ア太郎』。これは完全に予想外。このあたりが80年代的というか、エディがいてこそというか。


最後は両バンド出てきて、学園天国で〆。楽しゅうございました。

2007年7月5日木曜日

「休日情報Webサービス」をREST対応にする


サービス概要


日本の休日情報を提供する Web サービスです。
SOAP 1.1 および 1.2 に対応しています。REST にはサーバの都合により対応していません。


bear.mini の実験室 「休日情報 Web サービス」

いや、それはサーバの都合じゃなくて、実装してないだけだと思う。確かにASP.NETならSOAPによるXML Webサービスを書くのは簡単だけれども。(←私の勘違いのようでした。bear.miniさんにお詫びして訂正。)面白いと思ったので、自力でREST対応したらどうなるか書いてみた。

ってなわけで、サンプル書いてみた。ソースコードはzipにしておいた。


ポイントはいくつかあるが、



  • HTTPハンドラを使う
    .ashxファイルのこと。詳細は「HTTPハンドラによる動的コンテンツの提供」がおすすめ。

  • System.Xml.Serialization.XmlSerializerを使う
    HolidayInfoとかHolidayNameとかをXMLとして出力するなら、このクラスがお手軽。「ステップ7ハンズオン: XMLを利用したオブジェクトの永続化」や、@ITの記事あたりがわかりやすい。

  • System.Xml.Serialization.XmlRootAttributeやSystem.Xml.Serialization.XmlElementAttributeを使う
    XMLのシリアライズ結果を調整するには、上のカスタム属性をシリアライズ対象クラスに適用するといい。

  • Newtonsoft Json.NETを使う
    JavaScriptから呼び出すならXMLよりJSONのほうが嬉しいのだが、JSON関係は共通ライブラリに含まれていない。自分で書いてもいいんだけど、OSSとして公開されている(ライセンスはCC-BY 2.5)ものがあるのでそれを使う。


といった所か。

2007年7月4日水曜日

フリーセル

携帯アプリでフリーセルをやっているのだが、どうにも解けない問題がある。悔しいのでコンピュータに解かせようと考えた。いい練習なので自分で書いて実行してみた。


そしたら。2分ほど考え込み、得意げに(?)出してきた手順が2万ステップ弱。


アホなロジックにしたのは俺なんだけど、つい笑ってしまった。

2007年7月3日火曜日

マイコンBASICマガジン(ベーマガ)

まさにプログラマの原典!「ベーマガ」の魅力


暇なときに、リンク先のアンケートに答えてみる。(あとで書く)


Q. 『マイコンBASICマガジン』を読み始めたのはいつごろですか?


最初に読んだのは……覚えていないが、買い始めたのは11歳のとき、1986年12月号。
この年のクリスマスに親の許可が出て、MSX2(FS-A1)を買ったのだ。うちはファミコン禁止だったけれど、交渉の結果、MSXはなんとかOKになった。
ちなみにそれまでは電気屋の店頭に置いてある8ビットパソコンをいじったり、パソコンを持ってる友人の家に遊びに行って何時間もプログラムを打ち込んだりとかする、迷惑なガキだった。
話を戻して、ベーマガを買うようになったのはMSX2を買う直前からだ。

Q. 『ベーマガ』をどのように利用していましたか?

ゲームプログラムを打ちこんだ。基本はMSX(2)。他機種のゲームをMSX(2)に移植しようと思ったこともあったが、スクリーンの解像度は違うし、キャラクタとグラフィックは同時に出せないしで挫折した。Dr. Dのプログラムアドバイスみたいなのは参考にした(読みやすいコードにしろとか、スパゲッティは悪とか、サブルーチン化するとか、マルチステートメントにはしないとか)。
でもどちらかと言うと、(BASICのPLAY文を使った)ゲームミュージックプログラムの方が熱心だったかも。こういうのは他紙にはあまりなかったように記憶している。ゲームミュージックスコアは嬉しかった。小学校の音楽の時間、合奏曲を決めるときにアウトランのMagical Sound Showerを持ってったら音楽の先生から却下された(当然だ)。
パソコンショップの広告を眺めてたけど、2桁万円以上は小学生に手が出るはずもない。
あとは、ゲーム紹介読んだり、読者投稿読んだり、手塚一郎のファンタジー通信読んだり(ゲームブックが載ってたこともあったような)、そんなとこか?

Q. 思い出深い記事は何ですか?

(あとで書く)

Q. 競合誌と比べていかがでしたか?

(あとで書く)

Q. 『マイコンBASICマガジン』が今のお仕事にどのように影響していますか?

(あとで書く)

Q. あなたにとって『マイコンBASICマガジン』とは?

(あとで書く)