31日間ReSharper一周 ... それIDEAでもできるよ(その10)

いい加減飽きてはいたんだけど,素材は用意しちゃってたんで,もったいないから完投しよう。
#そうこう言いつつも,結構,自分メモとして役には立ってはいるんだ。

Day 23: 変数の導入(と、Ctrl+Shift+Rでリファクタリングすることの紹介)(http://matarillo.com/resharper/day23.php

Day 24: フィールドの導入(http://matarillo.com/resharper/day24.php

Day 25: パラメータの導入(http://matarillo.com/resharper/day25.php

「Introduce なんたら系」については,ReSharperとそんな違いは無いからまとめていいだろ。取り立てた違いといえば,ReSharperの「Ctrl+SHIFT+R:ここをリファクタリングする」コマンドはIDEAには無い。
だけど,前に紹介したとおりQuicklistで,メニューを自作できることを知ったので,似たようなことは簡単に真似ることができるよ。


使い始めてみてわかったんだけど,このQuicklistが大層便利なのだ。気をよくしたあたしは,前回紹介したgoto系Quicklistの他に,リファクタリング用のQuicklist,バージョン管理用のQuicklist,実行用のQuicklistを作り,それぞれ「Ctrl+ALT+G/R/S/E」に当ててるが,これが快適すぎてたまらん。:-D
ただ,冷静に考えるとメニューバーに「Refactor」ってあるリファクタリングに関しては,わざわざQuicklistを作るまでもなかったのかなぁと思う。何故かと言えば,もともと
 「ALT+R→すきなリファクタリング選択」
でできることが
 「Ctrl+ALT+R→すきなリファクタリング選択」
になっただけで,違いと言えばカーソル位置にポップアップメニューが表示される事による視点移動の少なさくらいしかない(それも些細な移動距離だし)。
でも,いいのだ。使ってる本人が満足しているのであれば,そんなつまらないことは気がつかないほうが幸せなのだ。:-P


あと,ReSharperにある青色ハイライトの消し方はIDEAも同じ。たしかに,このハイライトの消し方は,一見どこにも出てないように見えるし,いつの間にか消えちゃうので「そうゆうもんか?」程度にしか思ってなかったが,ちゃんと消し方を提示していたのだ。
それはどこかというと,画面下のステータスバー。試しに「Highlight Usages in File」を実行してみると,申し訳程度にステータスバーに何かメッセージが表示されていることに気付くだろう(いや,気付かんて)。


これを境にステータスバーも気をつけてみるようにしてるんだけど,結構いろんな情報を「さりげなく」表示してるんだよね。まったくもって侮りがたい。
しかし,もっといい表示場所はなかったんだろうか...


ちなみに,Introduce系そのものに関しては,ホントウに特別言うことはないんだ。いろんな意味で普通にこちらの期待通りにこなしてくれる。ただ,それだけってのも芸がないので,おもしろいプラグインを紹介しておく。
それは,SmartIntroduce。自慢しようとしてるワリについ最近まで,その用途を理解してなかったってのはナイショだ。:-P


大抵,Introduce系のリファクタリングを行う場合は,変更したい場所を選んでから目的のIntroduce項目を選ぶと思う。たとえば,「Introduce Variable...」をやろうと思ってるなら,その対象だってわかってるでしょ?実際,自分もそうやってたし,そうするもんだとしか思ってなかった。
この操作になれていたからこそ,SmartIntroduceを入れててもその実力に気がつかなかったんだと思う。
#すごく控えめなプラグインだし。


前置きが長くなったので,とっととSmartIntroduceの能力を紹介する。プラグインの名前から察しが付くと思うけど,このプラグインはIntroduceする対象の候補を挙げてくれるんだ。だから,「対象を選んで→リファクタリングのIntroduce項目を選ぶ」じゃなくて,いきなり「リファクタリングのIntroduce項目を選ぶ」としていい。すると,


こんな感じにカーソル位置からそのIntroduceに適した範囲をいくつか選んで候補を挙げてくれる。
あとは,自分が望む選択範囲を選ぶだけって寸法だ。ちなみに,Introduce系以外に「Extract Method」「Surround With」でも発動する(上の図は,Extract Methodを実行した時だと思う)。


これね,使ってみてわかったんだけどスゲー便利。IDEAの場合,Ctrl+W/Ctrl+SHIFT+Wという極めて強力な領域選択ショートカットキーがあるんだけど,それでも目的の範囲を選択しきるまで,何回かタイプしないといけない(当たり前だ)。なんで,領域選択そのものを端折れるSmartIntroduceの楽さ加減は群を抜いてる。
こんなに便利なら,もっと早くに使い方を調べればよかった。orz


さらに面白いことに,SmartIntroduceの設定画面には「I'm Feeling Lucky」という項目がある。


このGoogleでもおなじみの「I'm Feeling Lucky」が有効になっていると,カーソルがある場所がその条件(Ratingの高いヤツ)を満たしていれば候補選択をすっ飛ばして,勝手に対象領域を確定してくれる。たしかにこれ面白いんだけど,使い処が微妙でもある。
なんでもかんでも「I'm Feeling Lucky」を有効にしちゃうと,こっちの思い通りにならないので,有効にするとしてもConstant/Field/Variableあたりにしといたほうが良さそう。
#ちなみに,「Type of expression」はいじれない。いじれるのは「Rating」だけ。


このプラグイン,なかなか人気があるらしく,IDEA本体に取り込めって声も出てるみたい。
たしかに,こうゆうのはIDEAらしい。


おまけ:いつの頃からか下図のようにIntention Action(電球アイコン)に「Introduce variable」って出るようになった。


てっきりこれがSmartIntroduceなんだと勘違いしてたんだけど,どうやらこれはIDEA本体の機能らしい。
Hectorさんを目一杯きつく設定するとこのIntentionが出てくるので,おそらくInspectionのどっかの項目なんだろうな。


おまけ2:同じくInspectionの類で「Duplicate String Letral」ってのがあってだ,こんな感じに重複している文字列を警告してくれる。


それは,まあいい。ついでにIntentionも出てきて「定数化するか?(Introduce Constant)」と聞いてくるんだが,すでに該当文字列が定数化してあると,それに置き換えるか?とも聞いてくる。
#これも何気に気に入ってる機能のひとつだ。:-)


Day 27: メソッドの抽出(http://matarillo.com/resharper/day27.php

Day 28: スタティックメソッドの抽出(本気)とプロパティの抽出(http://matarillo.com/resharper/day28.php

Day 29: インターフェースがらみのリファクタリングhttp://matarillo.com/resharper/day29.php

ここらは,大きな違いもないし,まあ良きに計らってくれい。


若干の違いを言うと「シグネチャの変更」はメソッドだけじゃなくクラスに対しても行える(らしい)。ヘルプの受け売りで実際に使ったことはないが,クラスに対してシグネチャの変更を行うとジェネリクスの型パラメタが導入できるそうだ。
あと「プロパティの抽出」はIDEAにもない(ん?「Encapsulate Fields」がそうか?)。それと「スタティックメソッドの抽出」の対になるのか「Convert to Instance Method」ってのがある。


インターフェイスがらみのリファクタリング」って「Extract Interface」と「Use Interface Where Possible」くらいかな?まあ,とにかくリファクタリングメニューだけは豊富にある。「具象クラスが1つしかなかったんだけど,バリエーション増えるからインターフェイス導入しよう」なんてときは,どうゆう段取りでやっつけようかと考えるのが楽しい。この楽しさはviでコマンド組み立てる感覚に通じるところがあるな。


Day 30: リネーム(伝播リネームを含む)(http://matarillo.com/resharper/day30.php

「Move...」と並んで最もよく使うリファクタリングが「Rename...」。ショートカットキーはReSharperのF2と異なり,SHIFT+F6。これがHHKBだと押しづらくてね,RealforceにしたことでIDEAの操作感も3割増しって感じだ。
#単にファンクションキーがあるだけなんだがの。


伝搬リネームは当然ながらIDEAも備えている。ちょっと調べてみたらEclipseも備えていた。残念なことに,NetBeansは備えてなかった。:-(


唐突ではあるが,Renameを題材にIDEA, NetBeans, Eclipseリファクタリングの特徴を紹介したい。たまたま手元にあったのがClickだったので,こいつのControlインターフェイスClickControlにリネームするってのを,3つのIDEでそれぞれやってみた。


まずは,IDEA。


対象を選んでリネームを実行すると,こんなダイアログが出てきて変更したい名前を入力する。これは,まあどのIDEも一緒で,ダイアログに付いてるオプションにIDEごとの特徴があるって感じかな。


先のダイアログで「Refactor」ボタンを押すと,こんな画面が表示される。これがいわゆる「伝搬リネーム」ってヤツでしょ?「クラス名が変わるんだから変数名もいっしょに変えたら?」とご申告してくれる。


それで,さらに「OK」を押すとダイアログは閉じるが,まだリファクタリングは実行されずFindウィンドウがせり出てくる。


これも「伝搬リネーム」の一種で,自動的に「Find in Usage...」を実行し,コメントやJavaファイル以外に単なる文字列として記述している該当候補を検索してくれる。こちらは「これもやっとく必要ある?」と問いかけてるだけなので,必要がないのは候補から外せばいい(DELキーで除外できる)。んでもって,リネームする対象を決めたらFindウィンドウの下側にある「Do Refactor」ボタンを押して,やっとリネームが完了するってワケ。


覚えておいて欲しいのは「リネーム・ダイアログ」→「Findウィンドウ」と遷移すること。


次に,NetBeans


やっぱりNetBeansEclipseよりIDEAを意識してるだろ?って思うくらいUIが似てる。リネーム・ダイアログは見ての通りで,ここまで似せるなら「Preview」「Refactor」ボタンの位置も似せれば良かったのにと思うほどだ。:-P


NetBeansは,IDEAやEclipseみたいに変数名に対する伝搬リネームに対応していないので「Refactor」ボタンを押すと,即リファクタリング・プレビューが表示される。


このリファクタリング・プレビューはIDEAのFindウィンドウと同じように,リネーム・ダイアログが閉じて表示される。当然,これにも「Do Refactor」ボタンがあるので,プレビュー内容がよろしければ押す。
#面白いことに「Do Refactor」ボタンの位置も,IDEAと逆なのだ(これってワザとやってるの?)。


ここでも,覚えておいて欲しいのは「リネーム・ダイアログ」→「リファクタリング・プレビュー」と遷移すること。


最後が,Eclipse


Eclipseリファクタリングはウィザード形式で進めていくのが特徴でリネームも例外ではない。


EclipseのリネームはIDEA同様,伝搬リネームをサポートしているので,こんな感じで変数名のリネーム候補も指定できる。


でウィザードの最後に,リネーム対象の確定画面(プレビュー兼用)が表示されるんで,対象を絞り込んだら「Finish」ボタンでリネーム完了。


なんとなく回りくどかった気がするが,Eclipseだけが一連のウィザードで操作が完結する。これね,自分がずっとIDEA使ってたから気がつかなかったんだけど,NetBeansリファクタリング・プレビューがプレビューだと気付かない人がそこそこ居るんだ。プレビューを操作完了と勘違いして「Do Refactor」を押さない人をよく見かける。
なるほど,Eclipseと比べれば,あまり良いUIじゃないよね,これ。特にEclipseからNetBeansに乗り換えようとしてる人にとっては,結構なストレスになってるらしく「Do Refactor」の押し忘れにイラっとくるようだ。
#IDEAはともかく,NetBeansはちょっとUIを考え直した方がいいんとちゃう?


そうそう,伝搬リネームは便利ではあるんだが,コメントやJavaファイル以外の変更候補はコンテキスト非依存で,単なる文字列置換の対象で抽出しているので,十分吟味してから変更候補を確定したほうがいい。いくらIDEが提案してくれたからといって,楽観的にリネーム実行するとエラい目にあうよ。


Day 31: 安全な削除(http://matarillo.com/resharper/day31.php

これはその通りなんで,言うこと無い。