vim-users.jp

Hack #192: 任意の言語で任意のマクロを使う

Posted at 2011/01/01
このエントリーをはてなブックマークに追加

新年あけましておめでとうございます。いまこの記事はVancouver時間で30日木曜の夜5:54pm、もう外は真っ暗でございます。寒波到来で気温は-1Cまで下がり、凍えるような日々を過ごしております。といっても札幌より暖かいです。明日からは-4Cまで下がるそうです。

問題

さて皆様は日頃どのような言語を使っているのでしょうか。みんな大好きVim script、ブラウザ制御やサーバサイドの処理の記述にJavaScript、JVMを操作するためのJava、Hyper Textを記述するためのプリプロセッサであるPHP、そして究極にして高貴な言語Haskell、いろいろな言語を使っているものと思います。

いくつかの言語には、いつくかのレベルでのマクロの概念のサポートがあります。 有名な言語の中でもっとも強力なマクロを持っているものはCommon Lispであるという意見にほとんど異論はなさそうです。マクロの強力さを順に並べる事ができるとすれば、Schemeなど他のLisp系言語が、C言語のマクロとの間に位置するでしょう。一方Rubyをはじめとするスクリプト言語の多くはマクロを持っていません。言語自体が柔軟なのでマクロは不必要にものごとを複雑にするだろうとの判断でしょう。またJavaは柔軟でない言語にかかわらずマクロを持っていません。Annotationや、開発環境からの自動入力で対処せよとのことでしょう。

マクロは劇薬のようなものです。ちょっとした使用で、コードの冗長性を一気に排除でき、シンプルでエレガントで管理しやすいコードを生み出すことができることもあれば、作者でさえ二日後には読解不可能な難解なコードを生み出し、結局それがバグの温床になることもあります。これはとりわけ複数人でのコラボレーションで問題をより深刻にするでしょう。

複数人でソフトウェアを開発する際、あなたはマクロを多用したいものの、他の人にも使うことを強要したくないというシーンは多々あります。この場合、マクロを使用するなんらかのコードを記述した上で、MakefileなりRakefileなりbuild.xmlなりでマクロを適用し、それで生成されたコードをプロジェクトのレポジトリにコミットするという方法が実用的です。つまり、あなたが記述したコードそれ自体はあなた個人が管理し、そのコードを元に自動生成された別のコードのみをプロジェクトで共有するのです。

しかしながら、この方法は大変面倒です。

  • いちいちビルドしなければならない、あるいはビルドツールを記述しなければならない
  • 自分が記述したコードをコミットしないように気をつけなければならない
  • 自分が改変したビルドツールをコミットしないように気をつけなければならない
  • ちょっとしたマクロの適用でもいちいちビルドツールを修正しなければならない
  • コミット前のdiffの確認が行いにくい。コミットするのはいま編集しているバッファではなく、別で管理されているファイルであり、git-vimなどのツールとの連携がうまくいかない

解決

shadow.vimを使用します。

shadow.vimは著者により開発が進められているVimのプラギンです。これは任意の言語で任意の事前処理を行なうための薄いフレームワークです。コマンドや関数は提供されず、以下のようなファイル読み込み時と保存時のフックのみを提供します。

具体例で示しましょう。あなたはいまa.jsというファイル名のJavaScriptのコードを作成し、コミットしなければならない立場にいます。しかしあなたはJavaScriptなどという冗長な言語を記述する気はさらさらなく、CoffeeScriptで記述する気持ちしかありません(*1)。

まず、a.js.shdというファイル名のファイルを作成します。Vimで開き、一行目に以下のようなおまじないを書きましょう(*2)。

## coffee -csb

あとは以下にCoffeeScriptでコードを記述しましょう。適当に記述したところで、一旦そのファイルを完全に閉じ、a.jsという名前の空ファイルを作成してからそのファイルを開きます。

:!touch a.js
:e a.js

するとそこには先ほど編集したばかりのa.js.shdファイルの中身が展開されています。しかし実際にa.jsファイルには、coffee -csbコマンドの適用結果であるJavaScriptのコードが記述されています。これは以下のコマンドなどで確認できます(*3)。

:!cat %

補足ながら、shadow.vimとは直接関係ないことがらですが、適切なmodelineを与えることによって、.shdという拡張子でも適切なfiletypeを与えることができます。

筆者の使い方

筆者はshadow.vimを至る所で使用しています。先ほど例として挙げたCoffeeScriptを用いてのJavaScriptの記述以外に、Cのマクロを使用したVim scriptやPHPの記述、またRubyで独自に開発した独自言語処理系の適用、などなど。

shadow.vimはまさしくlife changingなフレームワークです。筆者のソフトウェア開発体験はこのプラギンによって大きく変わりました。非常に短い実装ながら、これはソフトウェア開発者個人に大いなる自由を与える哲学的かつ革新的なツールといえます。

参考文献

  • (*1) Hack #164: JavaScript開発環境 その2 CoffeeScriptを使う /vim-users-jp/2010/07/29/Hack-164.html
  • (*2) もしお使いのCoffeeScriptのバージョンが古ければ、-csbではなく-cs --nowrapというオプションを指定してください。
  • (*3) 著者はこれをQuickRunで代用しています。詳しくは以下の記事を参照ください。

追記

投稿するのがだいぶ遅くなってしまいました…。

ujihisa

もどる
blog comments powered by Disqus