読者です 読者をやめる 読者になる 読者になる

八発白中

はてなブログに引越しました。

Lisp Meetup #31 で「Dexador Rises」という発表をしました

今月の Lisp Meetup #31 で、拙作のHTTPクライアントライブラリの「Dexador」の話をしてきました。

事実上Drakmaの一人勝ち市場なんだけど、Drakmaって割とハマりがちだよね、っていう話に賛同を得られました。

Dexadorは現在v1.0.0リリースに向けて安定化を再優先に開発しています。

他の発表

UFO

@ta2gch さんからUFOの発表がありました。

UFOはRoswellスクリプトをインストールするためのRoswellスクリプトです。Web上に公開されたRoswellスクリプトを簡単にインストールできる「go get」相当の機能を提供します。書いた便利Roswellスクリプトをgistなどに公開すれば、ufo gist://fukamachi/clhs.rosなどでインストールすることが可能です。

本人がezoeコマンドを作ったときに、配布に困ったという体験から生まれたプロダクトのようです。いずれQuicklispに登録しよう、という話もしていたので、そうなればUFO自身のインストールも簡単になりそうですね。

あとclfreaks聞いてくれてありがとうございます!

Inquisitor

ぐれー (@sin_clav) さんのCommon Lisp文字コード・改行コード判定ライブラリ「Inquisitor」の発表がありました。

文字コード判定の処理や、処理系毎のexternal-formatの抽象化など、割と泥臭くて闇が深いということがわかりました。

DexadorでContent-Typeがtext/*だけどcharsetが指定されていないときに、現状はbabel:*default-character-encoding*を使ってエンコードするんだけど、Inquisitorを使えばある程度賢く判定できるかなー、と思ったりしました。ただ言語圏が取れないんだよなぁ。

あと速いの?とか気になったりしたけど、そういう老害的な発言はやめようという良心が勝ちました。

lem

佐野 (@snmsts)さんから、Common Lispで書かれたEmacsライクなエディタ「lem」の発表がありました。デモが中心なのでスライドはありません。

自分のプロダクトではないのに紹介する経緯としては、Emacs Lispよりマシな言語でカスタマイズしたいよね、っていうモチベーションだそうです。

TwitterのTLでは早速lemを試してみている人びとが観測されました。

まだCでSEGV出るより簡単に落とせるレベルとか言っていて、普段の開発で使うには怖いなーという感じだけど、Common Lispで書かれているし行数もまだ5000行程度なのでなんとかなりそう。Common LispシンタックスハイライトとSLIMEとEvilがあれば移れるかなぁという感じ。

lem自身がCommon Lispで書かれているので、エディタのカスタマイズ言語としてもフルのCommon Lispが使えます。デモでは実際にエディタ上でClackによるWebサーバ起動もしていました。この点はxyzzyと違ってまったく癖なく使えそうです。cl-ppcreとかも普通に動くってことだし、リーダマクロもたぶん動くよね。

作者ご本人の紹介記事はこちらです。

lizx.hatenablog.com

Clake

takagi (@kamonama) さんの、Common LispGNU makeライクなプログラム「Clake」の発表がありました。

主にRubyのRakeの置き換えを念頭に置いて開発しているようです。コマンドラインでの実行部分にはRoswellスクリプトが使われています。

発表後にclakeって名前がclackにtypoしがちなんだけど、っていうフィードバックをしました。「cla」とかするとclakeじゃなくてclackupが補完されたりしてちょっと使い勝手が悪い。早速Issueにて良い名前はないか募集がされています。案のある方はコメントすると良いのではないでしょうか。

github.com

Roswellのモメンタム

発表のうちUFOとClakeはRoswellスクリプトによる実装であり、他の発表でも何かしらの形でRoswellへの言及がありました (CIで使ってるよ、とか)。もはやRoswell Meetupと言っても過言ではない。この調子でRoswellがどんどん浸透していくと良いですね。

Roswell時代のCommon LispのWebアプリケーション運用

最近Quickdocs.orgフルスクラッチしました (2回目)。

今回のメインは裏側の月次バッチ処理でしたが、Webアプリ部分も多少変更をしました。特に運用方法が、Roswellを全面的に使うことで大きく変わりました。

Common LispのWebアプリ開発では、未だにこのブログの以下のエントリが参照されてるっぽいですが内容もかなり古くなっています。なのでこの機会に現代に合わせてアップデートしておこうと思います。

Roswell

何はともあれRoswellが必要です。

Roswellの紹介記事は以前書きました。

RoswellはCommon Lispスクリプトを簡単に実行できる機能があると共に、その配布も簡単にしています。

ros install <ライブラリ名>を実行すると、ライブラリのroswell/ディレクトリ以下のスクリプト~/.roswell/bin以下にコピーして利用可能にしてくれます。

使うライブラリ

QuickdocsではWebフレームワークにCaveman2を使っています。

Caveman2はClackに対応していてDBライブラリとの連携もある軽量なWebフレームワークです。

合わせてDBアクセスはdatafly、テンプレートエンジンはDjulaを使います。どちらもCaveman2のデフォルトです。

アプリケーション起動

開発時はREPLで (quickdocs-server:start) を実行すればHTTPサーバが起動しますが、デプロイすることを考えるとシェルから実行できる必要があります。

Clackはシェルコマンドの「clackup」を提供しているのでRoswell経由でインストールします。

$ ros install clack

Webアプリのプロジェクトルートにapp.lispというファイルがあるので、それをclackupコマンドに渡せばHTTPサーバが起動します。

$ clackup app.lisp
$ clackup --server :woo --port 38080 --debug nil app.lisp

ちなみに以前のQuickdocsはFastCGIを使っていましたが、今はWooで動いています。

ライブラリのバージョン固定

Webアプリケーションを長く運用していると、最新のライブラリではいつの間にか動かなくなっている、というようなことがあります。うまく動き続けている間は問題がありませんが、サーバの追加や移転をしようとしたりするときに困ります。

また、他の誰かがアプリケーションを動かすときに、自分と同じライブラリバージョンを使わないと挙動に齟齬が生じます。

Qlotを使えば、使うライブラリのバージョンを固定できるのでこれらの問題は解決します。clackupと同様、Roswell経由でqlotコマンドをインストールします。

$ ros install qlot

プロジェクトルートにqlfile を作って、qlot installをするとプロジェクトローカルにQuicklispがインストールされ、qlfile.lockができます。バージョンの固定にはこのqlfile.lockが必要なので、qlfileと合わせてコミットしておきます。

プロジェクトローカルのQuicklispを使うにはqlot execします。

$ qlot exec clackup app.lisp --debug nil --server :woo --port 38080

ホットデプロイ

デプロイ時に既存のプロセスを殺して新しいプロセスを立ち上げると、どうしてもサービスのダウンタイムが発生します。

これを防ぐためにServer::Starterを使ってclackupを実行します。これは新しいプロセスをforkしてHTTPサーバを立ち上げるのでportの競合なくファイルディスクリプタを新旧プロセスで共有し、新プロセスが正常に立ち上がったら旧プロセスを殺します。

clackupはServer::Starterに対応しているので使うのに特に難しいことはありません。

$ start_server --port 38080 -- qlot exec clackup app.lisp --debug nil --server :woo

死活監視

アプリケーションプロセスが、何らかの要因でいつの間にか落ちてサービス停止するのを防ぐためにプロセスの死活監視を行います。これにはSupervisorを使います。

リバースプロキシ

アプリケーションサーバの前段にNginxをリバースプロキシとして置きます。ここではアクセスログの出力や、エラー発生時にエラーページを返したり、その他静的ファイルの配信を行います。

デプロイ

デプロイ時に毎回SSHしてgit pullして再起動するのは面倒なので、ローカルから簡単にデプロイできるようにします。これにはFabricを使います。

こんな感じのfabfile.pyを書いておけば以下のようにデプロイができます。

$ fab server deploy

デプロイ時には以下のことをしています。

  • git pullする
  • qlot installする
  • supervisord からプロセスを再起動する

supervisorctl restartするとSupervisorがServer::StarterにSIGTERMを送って、Server::Starterが新しいプロセスを立ち上げます。立ち上がったら、Server::Starterがclackupにシグナルを送り、最終的にWooがリクエストを捌いてから終了します。

ただし、このfabfile.pyには実は問題があります。

git pullした時点でHTMLテンプレートや静的ファイルは更新されて再起動なしで配信されてしまうので、走っているプロセスとの不整合が起きます。

これを防ぐにはデプロイ時に毎回別ディレクトリにgit cloneして、サーバ起動前にすり替えるみたいなことが必要なんですが、Fabricはそういう気の利いたことをしてくれないので自分でPythonを書く必要があって面倒なので今のところ放置しています。

サービス監視

サービス監視にMackerelを使っています。

ただ、Quickdocsはまだそれほどトラフィックもないので、DBもアプリもバッチもリバースプロキシも1台のサーバに共存しているので、全く活かせている気がしませんが…。

f:id:nitro_idiot:20150804154702p:plain

まとめ

全体的にCommon Lispもこなれてきたなーと思います (毎回言ってる)。Roswellのおかげで簡単にスクリプトが書けるようになったのでServer::StarterやSupervisorなど、他のツールとの組み合わせが簡単になっています。

心残りはFabricかなー。もうちょっと何とかなりそうだけどPythonは書きたくないし。Common LispのデプロイツールがあればリモートのSwankサーバとの連携とかもできそう。

今回紹介したQuickdocsのWebアプリ部分はGitHubに公開されています。

Ansibleのplaybookはこちらです。

訳本「ヘルシープログラマ」を読む

以前、「The Healthy Programmer」を読んだ話を書きました。この夏にその邦訳の「ヘルシープログラマ」が出版され、僕のブログ記事を見ていただいた訳者の玉川竜司さんに献本いただいたので、今もう一度日本語で読み返しています。

f:id:nitro_idiot:20150802204203j:plain:w320

内容としては、普段座りっぱなしのプログラマ向けに健康を考えましょう、という主旨の本です。

プログラマは生産性を上げることが仕事の一部なので、普段から仕事の障害と思うものに対してセンシティブな方だと思います。

ずっとイスに座ってプログラム書いてると腰が痛くなって生産性が下がる。そのとき腰の苦痛を解消するために10万のイスを買ったりとか対症療法的な解決をしてしまいがちです。けど、そういう手段には当然ながら限界がありますよね。

かと言って今度は漠然と、運動しよう!とかいってフルマラソン走ったりする人もいるけど、それで逆に体を壊しても意味がないです。

そこでヘルシープログラマでは、もっと長期的な視点で無理なく健康を維持することで生産性を落ちないようにしようという提案をしています。特に、あまり「運動」に含まれそうにない「散歩」が生産性の維持に与える効果を説明してとてもおすすめしています。

と言っても、振り返ってみて実際に自分の生活に活かせているかというと難しい…。

f:id:nitro_idiot:20150730210703j:plain:w360

活かせている点は、以前のブログ記事を書いたときにエアロバイクを買って机の隣に設置したので、ちょっとしたスキマ時間に乗ったりしています。git pushしてTravis CIが回ってるのを待つ間に画面見ながら乗ってみたりとか。

一方で全く活かせてないところは、家の外に出る機会がほとんど無くなっていることです。それどころか、集中力を持続させるために部屋の移動すら少なくしようと、机の周りで何でも済ませられるようにしてみたり。最近はお茶を汲むためのインタラプションを少しでも軽減するために電気ポットを移動したり、安易に対症療法的な解決をしてしまっています。もっと歩いたほうが血の巡りも良くなって頭の働きも良くなるかもしれないのに。

引越しをしてから、以前は良くしていた散歩も全然しなくなっています。家の環境を良くしすぎなのと、家が大通り沿いであんまり外に出たくないなーっていう心理的な障壁が問題な気がしています。

本を頂いたおかげで良い振り返りの機会を得られたと思います。こういうとき、「ヘルシープログラマ」自体が全然説教臭くないので、変にひねくれずに素直にまた改善しようという気持ちになれるのも良いですね。

近くにいくつか公園もあることだし、これを機会にせめて一日20分程度の散歩を日常に取り入れたいものです。

ヘルシープログラマ ―プログラミングを楽しく続けるための健康Hack

ヘルシープログラマ ―プログラミングを楽しく続けるための健康Hack

Common Lispのコミュニティ事情

初対面の人と二人きりで話すという機会はあまりない。

「普段どんなお仕事をされてるのですか」

──もし訊いても良ければ。そう遠慮がちに言い添えた彼は、コタツを挟んで斜め向かいから好奇心旺盛な目でこちらを見ていた。

プログラマですよ」

そう答えてから、それが十分な情報にならないことに気づいて、「Webアプリケーションとかを作ります」と慌てて付け加えた。とはいえ、それでも大した情報量ではない。

彼はそれを聞いて感心したような表情を作ってからもまだ何か僕の言葉を待っているような様子だったが、僕がそれ以上は口にしないのを感じ取ると言い訳するように言った。

「いや、平日に急に三連泊なんて珍しくて」

その日唐突に山口県萩市を訪れることにしたのに大した理由があったわけでもない。この町は吉田松陰高杉晋作のふるさととして知られる。今も古い城下の残るちょっとした観光地だが、日本海側に面しており新幹線の停車駅からも空港からのアクセスにも恵まれず、訪れる人はそれほど多くない。いつか行こう行こうと思ってなかなか機会を得なかった土地だ。心が決まったのがたまたまこの三月だったというだけだった。普段から仕事は自宅でしているし、自宅に限らずどこにいてもリモート勤務ができる。数日の間、萩でする仕事も悪くあるまい。

「普段から自宅で仕事していますからね。実際どこにいたっていいんです」

東京のIT企業でもまだ浸透しているとは言えないリモート勤務について、この観光地でゲストハウスのオーナーをしている彼に理解が及ぶかという不安もありつつありのままを言ってみた。しかし、意外にも彼は納得したようだ。

「知人にもそういう人が何人かいます。プログラマでね。物を作ってメールで送ればいいんだそうです」

彼にはさまざまな「知人」がいるようだ。考えてみれば自然なことだ。ゲストハウスは多くの人が訪れて一夜して去っていく。宿泊客同士はなんらかの偶然で一時を共有する。多くの人の体験や思想が集って拡散していくハブとしての役割をゲストハウスはしており、各地に広範なネットワークを作っている。彼自身も旅好きのようで、冬の休みに観光に行く際は各地のゲストハウスを訪れて情報を得たりしているらしい。自分には全く馴染みのない世界である。

その日は僕の他に宿泊客はいなかった。障子を通して中庭の柔らかい光が居間に広がっている。平日の昼にゲストハウスに人がいる、というだけで珍しいのかもしれない。彼は視線を手元のPCに移しながら尚もひとりごとのように言った。

「それなら、ほとんど人と会う必要もないでしょう」

彼の意図するところがわからなかったが、僕はそれに答えて言った。「まあ、たまに決まった人とは会いますけれどね」

決まった人。顔が浮かぶのはよく会うCommon Lisperたちだった。「たとえばこの前の週末には友人を僕の家に呼んで、話をしたりお互いのプログラムについて意見を言い合ったりしました」

ほう。彼は顔を上げて意外そうに言った。「プログラマもそのように一箇所に集まったりするんですね」

プログラマといえば日がなコンピュータに向き合って、人にはあまり興味がないというステレオタイプが彼の頭にあるのかもしれない。もしくはすべてをWebで完結すればいいという先進的な人種だと思っているのだろうか。いずれにしても、正解からは遠い。僕は彼の方に向き直り、ゆっくりと言葉を選びながら言った。

プログラマというのは世間で思われている印象とは違って、存外に社会的な生き物なんですよ」

僕は周りで日常的に為されているオープンソース活動について話をした。プログラムを書くときは大抵一人だ。けれど、作ったプログラムを他人にも使ってもらいたいと思う。それを公開する。そこで賞賛や批判を得る。そうすると、それを一緒に改善しようという動きが出てくる。そういった独特の社会性が、プログラマの間では構築されている。

どれだけ伝わったかはわからない。けれど、彼はそれを静かに、ところどころで相槌を打ちながら聞いていた。

「積極的な人だと週末などに勉強会のようなものを開いて、新しい技術を一緒に学ぼうという活動もありますよ」

もちろん、個人的にはむやみに人に会うことは好きではありませんがね、と僕は少し笑って見せた。

今思えば彼にとって不思議だったのは、仕事では人に会わないという選択を良しとしておきながら、週末にはわざわざ人に会おうという二面性にあったのだと思う。だとすればその疑問には全く答えられていないわけだが、彼もそれ以上詳しく訊こうとはしなかったのでうやむやのままである。

Shibuya.lisp

とはいえ、ここ数年はあまり積極的にいろんな勉強会に参加することはしなくなった。唯一渋谷のLispコミュニティ「Shibuya.lisp」にだけはできるだけ参加し、まとまったネタがあれば発表するようにしている。

Shibuya.lispPerlコミュニティの「Shibuya.pm」にインスパイアされてhigeponさんやg000001さん、naoya_tさんを中心に作られたLispコミュニティだ。Common Lispに限らずLisp方言を全般に扱う。

当初は「Technical Talk」という、聴衆を多く集めてLispに関する発表を皆で聴くというスタイルのイベントを数ヶ月置きに開催していたのだが、最近では毎月開催の「Meetup」という小規模なものをメインに運営されている。

「Meetup」は毎月一度、平日の夜に渋谷のサイバーエージェントの会議室を借りて開催される。参加者と発表者はWebで募集され、毎回二〇人ほどが参加する。独特なのは月替りでテーマとなるLisp方言が変わるという趣向だ。Common LispSchemeClojureが順繰りにしばらく回っていたのだが、今年一月を最後にSchemeの参加者不足によりScheme回はスキップされており、今はCommon LispClojureが交互にテーマに選ばれている。

小規模ながらUstreamでの同時配信と、開催後の録画の公開も行っており、この点は非常に意欲的だ。これから参加しようか迷っている人はまずはShibuya.lispのWebサイトを見てみることをお勧めする。

知らない人も多いかもしれないが、実はShibuya.lispの運営は数年前にすっかり入れ替わっている。Technical Talkの定期開催も途絶えて二年ほど経った頃、g000001さんの提案により運営の見直しがなされたときに運営を担っていた人々は解散した。それと同時に、Shibuya.lispの継続を望む人々が手を挙げ、新たに第2期Shibuya.lisp運営チームが組織された。今Shibuya.lispを運営しているのはその人たちである。

新しい運営の最初の仕事はコミュニティの運営方針を考えることだった。今までの運営チームと同じである必要はないし、メーリングリストには新しいメンバーでできそうな意欲的なアイデアがいくつか挙げられていた。が、当然ながらそれらの方向性は、考えたメンバーによってバラバラだった。

メーリングリストで手を挙げただけの、互いに顔を合わせたこともない人々で話をまとめるのは難しい。特に、これからの運営どうしましょうかね、といった曖昧な内容をメールのやり取りだけでまとめるのは至難だろう。そこでまずは、新運営陣の顔合わせも兼ねて渋谷で対面のブートストラップミーティングを開くことになった。そのときは僕も新運営の一人として参加していた。

そのミーティングの席で僕はこんな発言をしたのを覚えている。

「そもそもShibuya.lispが何を目的として存在するのかを考えなくちゃいけないんじゃないですか」

単にイベントを開催するにしても、なぜ、というのが明確でなければいずれまた目的を見失う。Shibuya.lispは何かの手段であって、目的ではないんじゃないか、と。

僕のその言葉に一同黙り込んだ。さあ、Shibuya.lispをやる目的とは何だろうか──。

そのとき前運営の立場として参加していた佐野さんが言ったことは、図らずも新しい運営方針を決定付けたものかもしれない。

──「理由はそのコミュニティに集まった人々で作ればいいことで、我々はただその箱を用意すればいいんじゃないかな。だとすれば、『続ける』ということも十分目的になるよ」

そうして、今はTakehiko Nawataさん、Katsunori Kanda (potix2) さん、κeenさんを中心に「Lisp Meetup」が二年半の間、毎月続いている。東京のLispコミュニティは彼らに支えられている。

ELS 2015 @ London, UK

話は変わって、今年の四月にロンドンで「ELS (European Lisp Symposium)」が二日間に渡って開催された。僕は登壇者の一人として初参加、佐野さんは常連参加者の一人として日本から参加した。

ELSはヨーロッパのLisp方言全般のコミュニティだ。一年に一度、大学の講堂やホテルの一室を借りてイベントを開催し、ヨーロッパのさまざまな国から人々が集まる。共通言語は英語だ。

世界規模のイベントと言えば、数年置き開催の「ILC (International Lisp Conference)」というものもある。こちらは北米での開催が多いが、「International」と冠していることからも分かる通り、特に開催大陸が決まったものではない。二〇〇七年はケンブリッジで、二〇一二年には京都でも開催された。

日本からの参加者として見ればどちらも遠い「海外カンファレンス」ではあるけれど、ヨーロッパのコミュニティはILCとは参加者の顔ぶれや雰囲気は異なる。ELSはILCよりも若い参加者が多く、発表もアカデミックなものより実務寄りのものが目立つ。参加者もELSのほうがいくらか多いように見えるが、これはチケット代やビザの取得のしやすさの違いもあるかもしれない。

余談だが、以前は「ECLM (European Common Lisp Meeting)」というCommon Lisp限定のヨーロッパコミュニティもあった。しかし、種々の事情によりここ二年開催されなくなっており、こちらのイベントには僕は一度も参加したことはない。運営を担っていた人が抜けたこともあって、今後の開催も期待はできない。

海外の技術イベントに参加するときに興味深く思うのは、トークの間にある「休憩 (Coffee Break)」だ。二時間置きに三十分の休憩があるという具合で、その時間は皆席を立って思い思いの人と話をする。廊下に出るとコーヒーポットやクッキーが並ぶ。この休憩は文字通り休憩という意味もあるが、交流という意味が強い。登壇者に聞きたいことがある場合はこのタイミングでつかまえる。

https://twitter.com/meymao/status/590459858199130112/photo/1

一日目の最初はQuicklispの作者として知られる「Zach Beane」のKeynoteスピーチで始まる。「Quicklisp: On Beyond Beta」というタイトルで、Quicklispの概要と、プロジェクトのこれからについての話だった。

そのトークの中で意外にも彼は日本のコミュニティについて言及した。

日本語圏のCommon Lispコミュニティは本当に盛況のようで、Clack、qlot、fast-http、optimaなど多くの素晴らしいプロジェクトが見られる。 There also seems to be a real boom in the Japanese-speaking Common Lisp community, and I see some of the effects with great projects like Clack, qlot, fast-http, optima, and many others.

── els-london-2015/script.txt

敢えて彼が特別に「日本」について言及したのは、北米に住む彼にとっても、またおそらくヨーロッパから集まった聴衆にとっても、「日本」という国の人々の活動が意外で馴染みのない場所からのコントリビューションだと見えるからかもしれない。

その後の休憩で、佐野さんと共に、Zachと話す機会を得た。と言っても、会話はほとんど佐野さんに任せて、僕は隣に立っていただけなのだけど。

話は日本のCommon Lispコミュニティについてだ。彼は自身のトークで日本のコミュニティは「盛況」だと言及した。ヨーロッパに招待スピーカーとして登壇するCommon Lisperの彼にとって日本のコミュニティはどのように見えているのか。

──日本語が読めないからよくは分からない。ただ、日本人が作ったCommon Lispライブラリを多く見るから。

Tokyoという場所

日本のCommon Lispコミュニティについて考えると、Common Lispプロダクトを作っている日本人の多くは東京近郊に集中しており、Lisp Meetupで作者本人と出会うことも多い。これは東京に人口や企業の多くが集中しているという日本の地理的事情が無関係ではないだろう。

数年前に京都に住んでいたときに「Kyoto.lisp」というコミュニティを立ち上げようとした。しかし、京都の場合は近郊に人材が足りなさすぎた。初回は良かったが、二回目からはぐんと参加者の数も減った。最後には参加者も発表者も、兵庫や愛知、東京からの参加者を入れてようやく一〇人足らずという有り様だった。あるときその数少ない参加者の大学生から、東京の企業に就職が決まったので四月から参加できません、と聞いたときには東京という土地の引力に眩暈がしたものだ。その後コミュニティは運営に携われる人も見つけられず、数度のイベントを開いたきり続かずに終わってしまった。

GitHubで開発し、メールやTwitterでやり取りができるとはいえ、実際に会って話すことによるメリットはまだ確実にある。お互いに情報を交換し、問題意識を共有し、家に帰って形にする。このサイクルが東京のコミュニティではうまく回り、結果として海外カンファレンスで言及されるほどの存在感を得ているのだと思う。

僕は東京を住みやすい街ではないと思うけれど、人に会うということに関してはこの街ほど魅力的な場所はない。コミュニティの存在に感謝しつつ、今日も一人プログラムを書く。


この記事の下書きを読んで意見をくれた友人のMasatoshi Sanoと妻の@meymaoに感謝します。

コマンドラインからHyperSpecを開くRoswellスクリプト

コマンドラインからHyperSpecを簡単に開けるRoswellスクリプトを作ったので紹介します。

Roswellが何か知らない人はまずこちらの記事をお読みください。

blog.8arrow.org

昔はEmacsからemacs-w3mで開くことでEmacsから出ずに見られるように設定していたのですが、慣習として定着しなかったので最近はこのスクリプトでターミナルから開いています。

これならGUIのデフォルトブラウザで開けるので、Slackで質問されたときとかに「HyperSpec見ろ」と言ってURLを投げつけたりできて便利です。

インストール方法

Roswellをインストールしてください。

その後、上述のgistページからダウンロードして実行属性をつけ、PATHの通ったところに置くだけです。

$ wget https://gist.githubusercontent.com/fukamachi/3510ea1609c1b52830c2/raw/clhs.ros -O clhs
$ chmod u+x clhs
$ mv clhs /usr/local/bin

起動時間が気になるようなら、ros buildでexecutableを生成してしまえば待ち時間がほとんどなくなるのでおすすめです。

$ ros build clhs.ros
$ mv clhs /usr/local/bin

Roswellスクリプトにすると、こうして簡単に実行ファイルを吐けるので便利です。

使い方

clhsコマンドにシンボル名を与えるだけです。シンボルが見つかればデフォルトのブラウザでページを開きます。

$ clhs handler-bind
Opening "http://www.lispworks.com/documentation/HyperSpec/Body/m_handle.htm"

仕組み

初回にHyperSpecのシンボルリストのページを取ってきてパースしています。パースしたものは~/.cache以下に保存しており、次回以降はそのキャッシュを参照します。

キャッシュを作るために依存ライブラリとしてDrakma、Plump、CLSSが必要なのですが、一度キャッシュを作ってしまえば毎回ロードするのは無駄なので、キャッシュがないときだけこれら依存ライブラリがロードされます。この仕組みのためにQlotで使っているマクロwith-package-functionsをコピってきていて、その部分だけ少し技巧的です *1

Drakmaのリクエストが200以外を返したときは地味にデバッガからリトライができる、とかも対応しています。Common Lispのrestartの簡単な使い方として参考になるかもしれません。

真似して欲しくないところとしては、terminateにチルダを含むメッセージを渡すことが考えられてないことですが、スクリプト内で使うだけなのでわざわざエスケープ処理はしていません。

ソースコードは以下に貼り付けておきます。ライセンスはMITです。どうぞご利用ください。

*1:このマクロが必要な理由は、Common Lispのリード時エラーを防ぐためです。たとえばDrakmaがロードされていない環境で、シンボル drakma:http-request を含む式をリードしようとすると、Common Lispのリーダがパッケージを探しにいってエラーを吐きます。