Scalaインタプリタ上でscaladocを検索できるInteractiveHelpを作りました。
みなさん、「Scala スケーラブルプログラミング」読みましたか?
俺はまだデスおつかれザマァm9(^Д^)
ちょろっとコード打って動作確認しながらコーディングする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>
どんなもんなの?
以下のスクリーンショットをご覧ください。
ごらんのとおり、インタプリタ上でscaladocを閲覧することが出来ます。
自分で作っておいて何ですが、鼻血が漏れ出すくらい便利なのでぜひ使ってやってくださいm(_)m
クラス/オブジェクトの検索
scalaのインタプリタ上でh("List")と入力すると、"List"に一致するクラス/オブジェクトの一覧が表示されます。
scala> h("List") 0:Class scala.List 1:Object scala.List
さらにつづけて、h("List")(0)と入力してみましょう。
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と入力します。
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)のように、一覧の番号に対応する番号をさらに指定すると、そのメソッドの詳細が確認出来ます。
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")のように、パッケージ名を指定するとそのパッケージに属するクラス/オブジェクト/パッケージが一覧表示されます。
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を渡すと、前方一致で該当するものを検索します。
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をブラウザ上で見ることが出来ます。