IDEを使いましょう

タグ: Laravel   NetBeans   PhpStorm  

この記事は、Laravelリファレンス発売記念!の2015年12月20日の記事です。

軽いエディターでさくさくと作るのも楽しいものです。私もちょっとした修正はvimやkateなどのエディターを利用します。Windowsでは決まったエディターはありません。昔はSakuraエディターを使っていました。新しいエディータが出ると、まず数時間使ってみます。

とはいえ、本格的にソースを読んだり、書いたりするにはIDEを使います。IDEはたくさんの機能があり、いろいろと手助けをしてくれます。しかし、そうした超便利機能はあまり使いません。

IDEでは基本的なコード補完と、コードを追いかけるための機能をメインに使います。これがエディターとの大きな違いです。あるとないとでは効率が違います。

PhpStormについての詳細は、PhpStormでLaravel5快適開発 おさらいというYTakeさんの過去記事もあります。参照してください。

コード補完

コード補完はたった今編集している時点で、入力を補助してくれる機能です。日本語入力のように、いくつか言葉を入力していくうちに、候補を絞り込んでくれます。

エディターでも、基本的な構文や関数名を補助したり、編集しているそのコード内のメソッド名を補助してくれる程度のものは結構あります。しかし、IDEのコード補完はもっと強力です。特にクラスを判断して、メソッド名や引数を補助しつつ、引数までも示唆してくれます。

namespace App\Models;

class Cup {
    /**
     * 補完の説明用ダミーメソッド
     *
     * @param string $drink
     * @return string
     */
    public function pourDrink($drink)
    {
        return $drink.'を注いだ!';
    }
}

このようなクラスがプロジェクト内のどこかにあり、それを利用するコードがあるとします。

$cup = ☆

☆のところでCupと入力すれば、Cupを含んだクラスや名前空間の候補がリスト表示されます。その中でApp\ModelsCupを選びます。

$cup = new App\Models\Cup();
$cup->☆

☆の直前まで入力します。元のクラスには'pourDrink'メソッド一つしかありません。ですから、このメソッド名が引数付きで表示されます。それを選びます。

$cup = new App\Models\Cup();
$cup->pourDrink(☆);

IDEにより、表示は異なりますが、共通なのは引数があることを認識し、$drinkを入力できるように☆の位置にカーソルが移動され、'drink'を入力しろと表示されます。メソッド定義の直前のドキュメントブロックで$drinkがstringであると指定してありますので、それも表示されます。

このような動作をプロジェクト内の全クラスに対して実行可能です。そのためにIDEは大仕事をしていますので、軽量なエディターよりメモリも喰いますし、動作も緩慢です。

しかし、Laravelのような便利であるが、クラスもメソッドも多くあるフレームワークでは、こうした機能が役に立ちます。

Laravelの弱点

こうしたコード補完に関して、Laravelは弱点を持っています。一つはファサードです。

ファサードは実体クラスの静的記法を提供する仕組みです。File::moveメソッドは静的メソッドのような書き方ですが、実際は実体クラスがインスタンス化され、そのmoveメソッドが呼びだされます。

簡単に言えば、ファサードのFileというクラスはコードとして存在していません。存在していませんから、補完できません。

それをどうにかしてくれるのが、'barryvdh/laravel-ide-helper'です。

composer require barryvdh/laravel-ide-helperでインストールできます。その後、config/app.phpファイルの'providers'配列に、Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,を追加します。

データベースを設定し、php artisan ide-helper:generateを実行すると_ide_helper.phpファイルが生成され、その中にファサードの入力を補助できるようにするコードが準備されます。(データベースが使用できなくてもエラーメッセージが表示されるだけで、_ide\helper.phpファイルは生成されます。)

もう一つの弱点はマジックメソッドです。たとえば実装を切り替えるためにドライバーシステムを採用しているキャッシュクラスなどでは、自クラスで見つからないクラスメソッドの呼び出しに対し、ドライバークラスのメソッドを呼び出すように__callメソッドを使用しています。

マネージャーのクラスからドライバーのメソッドも呼び出せるので、実装を切り替えられるという長所があるのですが、補完に関してはお手上げです。逆に言えば、ドライバー側で提供されるメソッドは、比較的覚えやすくなっていますので、よく使うメソッドは暗記してしまうか、スニペット機能(コードテンプレート)を活用するのがよいでしょう。

もう一つあります。Laravelのサービスコンテナを使用し、クラスインスタンスを取得した場合、そのインスタンスのクラスをIDEは認識できません。代入文に対してPHPドキュメントでクラスを指定できるIDEもあります。PhpStormの場合は次の構文です。

/** @var \Illuminate\Contracts\Filesystem\Filesystem $abc */
$abc = App::make('登録名');
$abc->☆

☆の位置でFilesystemクラスが持っている、ファイル/ディレクトリー操作メソッドが候補として表示されます。この指定方法はNetBeansで使用できません。NetBeansとPhpStorm両方で利用できる指定方法は以下の記法です。

/* @var $abc \Illuminate\Contracts\Filesystem\Filesystem */
$abc = App::make('登録名');
$abc->☆

同様に☆の位置でメソッド名の補完が効くようになります。ちなみにNetBeansでは上記のような代入文の前でvdocと入力しTabキーを叩くと上記のコメントに展開されます。vdocと入力した場所以降の行で変数を探して、変数名として埋め込みます。上記の例では、さすがにクラス名を自動補完とは行きませんが、Filesystemを入力しCtrl+spaceキーで補完候補クラスを表示できます。

下記のようなコードであれば、一発で変数名もクラス名も埋め込まれます。

use Illuminate\Contracts\Filesystem\Filesystem;

…(省略)…

vdoc[Tabキー]
$abc = new Filesystem();

この場合はTabキーを押せば、/* @var $abc Filesystem */に展開されます。

なおIDEヘルパーには、PhpStormのメタファイルを作成する機能があり、これによりインスタンスやヘルパーなどの戻り値をPhpStormに伝えることにより、コード補完を強化できます。(メタファイルはPhpStromの機能ですから、NetBeansでは動作しません。IDEヘルパーの生成に任せるだけでなく、自分用に改造していくことをおすすめします。)

コード・リーディング

コードを読む場合こそ、IDEは便利です。IDEはある程度、クラスの継承関係を把握していますので、メソッドやクラスへの適切な移動が可能です。Seach Everything的な検索でも可能ですが、同じような名前がヒットする場合は自分であたりを付ける必要があります。(逆に言えば、名前空間やクラス名から、あたりを付けられる上級者であれば、Seach Everything機能のある軽量なエディターでも十分なのです。ですから、Taylorさんは普段エディターを使用していますね。)

コードを表示したいクラスやメソッドにカーソルを移動し、Ctrl+Bか、Ctrl+右クリックです。IDEにより細かい動作は異なりますが、キーバインドの定義は共通なものが多く、これで宣言部へ移動できます。

これを使い、次々と移動していくのですが、コードを読んでいるとジャンプ前後の場所に移動したいことが多くあります。

PhpStormの場合はCtrl+Alt+左右の矢印で、行ったり来たりが簡単にできます。

NetBeansの場合は、ファイル単位で前後できます。また、以前の編集位置へ戻ることもできます。ただ、今の場所から以前の編集位置へ移動できますが、一度移動してしまうと逆に今の位置に戻る機能がありません。「行ったり来たり」しやすいのはPhpStormです。

NetBeansのデフォルト設定ではでは、こうした移動にキーバインドが割りつけられていないようです。編集ファイルのタブの下、ソースと履歴ボタンの右にある、小さなアイコンの一番左から3つが、これらの移動機能です。

移動の場合も、ファサードやコントラクト(インターフェイス)の実体へ移動したい場面は多いため、「Laravelソースコードの歩き方」の記事を参考にして、実体クラスへの移動方法を理解しておきましょう。

IDEをどう使いこなすか

私の場合、IDEやエディターを使いはじめるとき、まずデフォルトのキーボード・キーバインド(キー設定、ショートカット)を全部削除してしまいます。それから基本的なカーソル移動と、検索、置換などを自分の趣味に合うように設定し、それから使い始めます。こうした基本的なキー操作は自分の中で統一しておき、ストレス無く使うのが肝心です。

最近のIDEはこうしたキーの設定やコードハイライトのテーマなどに、独自の名前を付け保存できるようになっています。たいていデフォルト設定は、defaultとかいう名前で予め保存されています。それを利用し、元に戻すこともできます。もしデフォルトの設定が保存されていないようなら、最初に保存しておきましょう。そうすれば、安心してキーバインドを削除できます。

本サイトは、DBが吹っ飛んだり、サイトシステムを更新するたび、古い記事は捨てています。こうしたもう存在しない記事でも、このポイントをよく紹介してきました。重要な点は:

「自分がIDEに合わせるのではなく、IDEを自分に合わせる」ことです。

プログラムごとに決められているキーボード・キーバインドは、決して効率的に配置されているわけでも、わかりやすく意味付けされているわけでもありません。もちろん、「できるだけ効率的かつわかりやすく」配置する努力はされていますが、新しい機能を付け加えるときに、古い機能のキーバインドを変更することはまれです。コンパチビリティのために、現状一番良い割り付けができません。今までのユーザーのことを考え、できるだけ変更が少ないように割りつけられます。そして、段々と系統立てが複雑になり、真新しいユーザーはとても使いこなせなくなるのです。

また、キーボード・キーバインドと機能をどのように結びつけると、利用しやすいかはユーザーにより異なるはずです。今まで使ってきたソフトの影響もあるでしょう。しかし、指の長さやタイプのくせなどにより、合わないキーバインドを使い続けていることも多いはずです。

シンプルに、自分で考えて、自分にピッタリ合うキーバインドを採用しましょう。自分というユーザーに合わせて、インターフェイスを設計するのです。(ショートカットの割り付けも、ユーザーインターフェイスですよ。)

また、デフォルトのキーバインドの中には、「自分がよく使う」機能の隣に、「破壊的で後戻りできない」機能が割りつけられていることもあります。タイプミスで何か理解できないことが起き、元に戻せなくて焦る経験をしたことはありませんか。

キーバインドを削除しておけば、ミスタッチで余計な機能を起動することもありません。安心し、自信を持ってキーバインドが使えます。

キーバインドとメニューと住み分けましょう。繁用しない機能、たまに使うだけの機能にはキーバインドを割りつけず、メニューの場所を視覚的に覚えておきましょう。メニューは視覚的なフィードバックもあり、たまに使う機能を思い出すために最適です。

逆に、よく使う機能はキーボード・キーバインドを割り付けます。基本的に指が覚えるでしょう。そしてたまに眠くなり、指が思い出してくれなくても、自分の中の「意味」的な部分に合わせて割りつけていれば、思考的に思い出せます。思考により思い出せないほど鈍っているなら、休みを取る時です。