Haxe de REPL


Haxeにも、REPLがあるって知ってましたか?

正確にはRubyやPythonみたいにbuilt inではないのですが、ライブラリでREPLを実現できる方法がありましたので紹介します。それがihxライブラリです。

ihx

バックグラウンドでは Neko がうごいて、対話型の実行を実現しています。動作は結構軽快。試した環境はLinux(LinuxMint)、MacOSX(Marvericks)では問題なく動きました、 changelogをみると、Windows環境にも対応しているみたいです。軽く触ってみて分かって事を以下書いていきます。

じゃあ、実際にインストール、起動してみます

インストール方法
haxelib install ihx
起動方法
haxelib run ihx

起動すると >> がでてきて、対話モードスタート。Python >>> より1個少ないです。それでは実際にやってみます

型を定義する

 >> var str:String = "String type" 
 String : String type

 >> str = 100  
error: Int should be String
  • 当たり前ですが、コンパイル時と同じように定義ができます。文字列型に数値型をいれようとするとちゃんと怒られます

変数の定義

 >> str = "aaaa";

  • コンパイルHaxeと同じように、文末にセミコロンをつけます。ですが付けないとエラーにはならず、出力内容が変化します。次を見てください

文末にセミコロンをつけない

 >> str = "aaaa"
 String : aaaa
  • このように定義した値が返り値として、コンソールに出力されます

複数の定義を1行で実現する際にセミコロンで区切る

>> var a = 1; var b = 2;
  • これはOKですが次の複数定義だと、先頭の変数名しか定義されません
>> var a, b = 1;
  • aだけが定義されたことになっており、bは未定義の状態

for文も可能

>> var data = [1,2,3]                      
Array<Int> : [1,2,3] 

>> for(d in 0...data.length){trace(data[d]);}
IhxProgram_3204.hx:25: 1
IhxProgram_3204.hx:25: 2
IhxProgram_3204.hx:25: 3
Void : false

あくまでもNeko

>> import js.Jquery
error: You cannot access the js package while targeting neko (for js.Jquery)
  • あくまでも対話できるのはNekoのAPIなので、JS APIを呼ぼうとしても怒られます

複数行に渡る式の際は(バックスラッシュ)で定義する

>> if (true) { \
.. 1 + 2; \
.. }
Void : 3
  • Syntax Errorとかがあると最初からやり直しなので、長い式はREPLには向いてないです

無名関数

>> var incl = function(i) { return i += 1; }       
Int->Int : #function:1
  • 問題なく定義できます

Lambda

>> using Lambda
>> [1,2,3,4].map(incl)                       
Array<Int> : [2,3,4,5]
  • Lambda宣言すれば、普通に使えます

Enum型

>> enum Animal {\ 
.. CAT;\ 
.. BOG;\ 
.. LION;\ 
.. } 
  • Enum型も普通に宣言できます。バックスラッシュがちょい面倒ですが。

オレオレclassを呼び出す

class Main {
  public static function hoge() {
    return "hoge";
  }
  public static function main() {
  }
}

>> addpath /Haxe3/Src/ 
added path: /Haxe3/src

>> Main.hoge() 
String : hoge
  • 呼び出すファイルのクラスパスを addpath で追加すればOKです。pathというコマンドで実際に追加されたかどうか確認できます

変数の再定義はできない

>> var a = 10      
Int : 10

>> var a = "test"  
error: String should be Int
  • コンパイルHaxeだと、再定義はできますが、ihxだと再定義はできないです。

いままで実行したソースを出力する

>> print 
Compilation:
haxe -neko /tmp/ihx_out_1267.n -cp /tmp -main IhxProgram_1267.hx -cmd neko /tmp/ihx_out_1267.n -cp /Haxe3/src
Program:
1: #if !macro 
2: import neko.Lib;
3: 
4: enum Animal {CAT;BOG;LION;}
5: 
6: class IhxProgram_1267 {
7:     public static function main() {
8: 
9:           Lib.getClasses();
10:         Std.random(10);
11:         Main.hoge();
12:     }
13: }
14: #end 
  • これをみれば、バックグラウンドの仕組みがなんとなく見えてきます。/tmpファイルにダイナミックにファイルをつくって、実行しているんですね。 addpath で追加したクラスパスも引数 -cp として定義されています

completion機能はない

  • RubyのREPLのように変数名や、メソッド名を補完してくれる便利機能はまだ実装されてないようなので、すべて手打ちです。

個人的には、ちょっとした構文を確認したり、正規表現のマッチングをihxで確認してから、printで出力してソースに貼付けたり、便利に使えるのではないかと思いました。IDEAを起動するよりihxたたいたほうが早いですしね。

次は tkawachi@github さんです、よろしくお願いします。