( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

Scalaインタプリタ上でscaladocを検索できるInteractiveHelpを作りました。

みなさん、「Scala スケーラブルプログラミング」読みましたか?
俺はまだデスおつかれザマァm9(^Д^)


Scalaスケーラブルプログラミング[コンセプト&コーディング] (Programming in Scala)


scalaには対話型実行環境(インタプリタ)がついてます。


ちょろっとコード打って動作確認しながらコーディングするLLライクな開発スタイルが可能なんです。
IDE向けのscalaプラグインも、IDEと統合されたインタプリタがあれば、と常々思っています。
というかあるべきだろJK。


ただ、scalaのインタプリタで決定的に不足している機能があります。
それは……


ヘルプの検索です!!


scalaには、scaladocというjavadocと同じHTML形式のAPIドキュメントがありますが、基本ブラウザから閲覧するものです。

インタプリタでコード書こうと思って、「あれ、あのクラスってどんなメソッドあったけ?」と思ったら、おもむろにブラウザを起動してAPIドキュメントを開いて、目的のクラスのリンクをクリックして……UZEEEEEEEEEEEEEEE!!!!!!!!!


これがpythonだったら、help(dict)と入力するとドキュメントが見れるし、オブジェクトの持つプロパティはdir( (1,2) )なんかで参照できる。なぜこの機能がscalaにはないんだっ!?


なければツクレカスってことで作りました。


InteractiveHelp
yuroyoro/InteractiveHelp · GitHub

セットアップ

README.textileにも書いてありますが、まずgithubからプロジェクト一式をダウンロードします。


次に、添付されているscala-2.7.5-apidocs-fixed.zipを解凍して、出来たディレクトリを環境変数SCALA_DOC_HOMEに設定します。
(実は、実行するscalaランタイムのdoc/apiにhtml一式を配置しても参照できる)


実行は、InteractiveHelpのjarをクラスパスに通して、インタプリタ上でcom.yuroyoro.interactivehelp.Helpオブジェクトのメソッドを全てimportします。


こんな感じです。

$ scala -cp InteractiveHelp/interactive-help-1.0.jar
Welcome to Scala version 2.7.5.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import com.yuroyoro.interactivehelp.Help._ 
import com.yuroyoro.interactivehelp.Help._

scala> 

どんなもんなの?

以下のスクリーンショットをご覧ください。

f:id:yuroyoro:20090901132812p:image

ごらんのとおり、インタプリタ上でscaladocを閲覧することが出来ます。


自分で作っておいて何ですが、鼻血が漏れ出すくらい便利なのでぜひ使ってやってくださいm(_)m

クラス/オブジェクトの検索


scalaのインタプリタ上でh("List")と入力すると、"List"に一致するクラス/オブジェクトの一覧が表示されます。

scala> h("List")
   0:Class scala.List
   1:Object scala.List


さらにつづけて、h("List")(0)と入力してみましょう。
f:id:yuroyoro:20090901132813p:image

scala> h("List")(0)
=== scala.List ==================================================
sealed abstract class List[+A]
  extends Seq[A] with Product

  A class representing an ordered collection of elements of type
  a. This class comes with two implementing case
  classes scala.Nil and scala.:: that
  implement the abstract members isEmpty,
  head and tail.

================================================================ 

res11: com.yuroyoro.interactivehelp.Document = Class

Listクラスのドキュメントが表示されました。

メソッドの検索

Listクラスが持つメソッドを知りたい場合は、続けてh("List")(0).mと入力します。
f:id:yuroyoro:20090901132814p:image

scala> h("List")(0).m
   0:def + [ B  > : A ]( x : B ) : List [ B ]
   1:override def ++ [ B  > : A ]( that : Iterable [ B ]) : List [ B ]
    Appends two list objects.

   2:def - [ B  > : A ]( x : B ) : List [ B ]
    Computes the difference between this list and the given object
    x.

   3:def -- [ B  > : A ]( that : List [ B ]) : List [ B ]
    Computes the difference between this list and the given list
    that.
...

メソッドの一覧が表示されました。


h("List")(0).m(1)のように、一覧の番号に対応する番号をさらに指定すると、そのメソッドの詳細が確認出来ます。
f:id:yuroyoro:20090901132815p:image

scala> h("List")(0).m(1)
override def ++[B >: A](that : Iterable[B]) : List[B]
  Appends two list objects.

Overrides
  Seq.++

res13: com.yuroyoro.interactivehelp.Document = Method
パッケージの検索

h("scala.util.regexp")のように、パッケージ名を指定するとそのパッケージに属するクラス/オブジェクト/パッケージが一覧表示されます。
f:id:yuroyoro:20090901132816p:image

scala> h("scala.util.regexp")   
   0:Class scala.util.regexp.Base
   1:Class scala.util.regexp.PointedHedgeExp
   2:Class scala.util.regexp.SyntaxError
   3:Class scala.util.regexp.WordExp

res14: com.yuroyoro.interactivehelp.Document = Seq
検索結果の種別

検索結果の種別は、最後に以下のように、出力されます。

res11: com.yuroyoro.interactivehelp.Document = Class

種別としては、以下の種類があります。

None 該当なし
Seq 複数件が該当。この戻り値のオブジェクトに(0)や("Name"),('Nam)のように、Index番号/名前を指定することでさらに絞り込める。Seqは、With scala.Seq[Document]型なので、filterやmapなどが可能。
Package パッケージが該当。PackageもWith scala.Seq[Document]型。
Class クラスが該当
Object オブジェクトが該当
Method メソッドが該当
Value クラスが持つフィールドが該当


検索結果のSeqやPackageはSeq[Document]型なので、filterやmapなどが可能です。

scala> h('reg)(5).foreach( c => println(c.name ) )
Base
PointedHedgeExp
SyntaxError
WordExp
検索結果の絞り込み

複数件が該当するような結果(種別がSeqやPackage)の場合、戻り値のオブジェクトに(0)でIndex番号を指定したり、("name")とStringで名前を指定すると絞り込みが出来ます。


('Lis)のように、Symbolを渡すと、前方一致で該当するものを検索します。
f:id:yuroyoro:20090901132817p:image

scala> h("scala.actors")('Act)                    
   0:Class scala.actors.Actor
   1:Object scala.actors.Actor
   2:Object scala.actors.ActorGC

res25: com.yuroyoro.interactivehelp.Document = Seq
ブラウザでの閲覧

検索結果の種別が、Class/Object/Method/Valueの場合、続けて".o"と入力すると、対応するscaladocをブラウザ上で見ることが出来ます。

その他のコマンドについて

こちらのREADME.textileを参照してください。

README.textile

これから

まずは、scalaのtrac上のソースファイルをブラウザで見る機能を付けます。


あと、ちゃんとテスト書いてない(!!!)のでテスト書きます。


あと、読み込むscaladocはwell-formedなXHTMLでないとエラーになるため、これを改善したいと思います。
現在は、scala公式のscaladocのいくつかはタグの閉じ忘れなどがあって読み込めないため、仕方なく修正したscaladocを同梱してそれを利用するようになっているのです。


最終的には、vscaladocのようなdocletとして実装して、ヘルプ用のファイルをソースから生成して、それを利用する形にしたいと考えています。