Haxe3.2でPython出力を試す


[Haxe 3.2](http://haxe.org/download/version/3.2.0/)からPython出力が可能になったので、試してみます。

# インストール

## Haxe 3.2のインストール

Haxe公式の[Downloads](http://haxe.org/download/)から最新版をダウンロードしてインストールします。

Macでhomebrewを使っているなら下記でもOKです。

```
$ brew install haxe --HEAD
```

もしくは、[Building Haxe](http://haxe.org/documentation/introduction/building-haxe.html)を参考に自分でビルドします。

## Python3.xのインストール

他にたくさん記事があるので省略。
なお、いまのところHaxeが出力可能なのはPython3だけのようです。

# Haxe/Pythonチュートリアル

## Hello World

[公式のHello World](http://haxe.org/documentation/introduction/language-introduction.html)でPython出力をしてみます。

まずはHelloWorld.hxを下記の内容で作成。

```hx:HelloWorld.hx
class HelloWorld {
    static public function main() {
        trace("Hello World");
    }
}
```

上記をhaxeでhelloworld.pyにコンパイル。

```sh
$ haxe -main HelloWorld -python helloworld.py
```

-mainオプションがメインクラス、-pythonオプションがPython指定で出力するファイル名です。詳細は[Compiler Usage](http://haxe.org/documentation/introduction/compiler-usage.html)参照。

もしくは、下記のようにcompile.hxmlを作成しコンパイルする方法もあります。

```hxml:compile.hxml
-python helloworld.py
-main HelloWorld
```

```sh
$ haxe comple.hxml
# 上記の haxe -main HelloWorld -python helloworld.py と同じようにhelloworld.pyが出力される
```

コンパイルが成功したら、出力されたhelloworld.pyを実行します。

```sh
$ python3 helloworld.py
Hello World
```

無事、Hello Worldが出力されました。

なお、このとき出力されているhelloworld.pyは下記のようになっていました。

```py:helloworld.py
class HelloWorld:

	@staticmethod
	def main():
		print("Hello World")



HelloWorld.main()
```


## コマンドライン引数の取得

[Sys.args](http://api.haxe.org/Sys.html)からコマンドライン引数が取得できます。

```hx:Main.hx
class Main {
  static public function main():Void {
    var args = Sys.args();
    for (arg in args) {
      Sys.println(arg);
    }
  }
}
```

コマンドライン引数のリストを[Sys.println](](http://api.haxe.org/Sys.html))で出力します。

```sh
$ haxe -main Main -python main.py
$ python3 main.py foo
foo
$ python3 main.py foo bar
foo
bar
```

このとき出力されたmain.pyは378行ありました。（長い！）
おそらく、[Sys](http://api.haxe.org/Sys.html)を使用するようになったためで、若干余分なものも含まれています。
とはいえ出力されたPythonを読んでみるのもおもしろいでしょう。

## ファイル出力

[sys.io.File](http://api.haxe.org/sys/io/File.html)でファイル出力をしてみます

```hx:Main.hx
import sys.io.File;

class Main {
  static public function main():Void {
    var output = File.write("output.txt");
    output.writeString("test\n");
    output.close();
  }
}
```

```sh
$ haxe -main Main -python main.py
$ python3 main.py
$ cat output.txt
test
```

### ファイル出力をcodecsで行う場合

ファイル出力に[python.lib.Codecs](http://api.haxe.org/python/lib/Codecs.html)を使用すると、Pythonのcodecs相当になります。

```hx:Main.hx
import python.lib.Codecs;

class Main {
  static public function main():Void {
    var file = Codecs.open("output.txt", "w");
    file.write("test\n");
  }
}
```

```sh
$ haxe -main Main -python main.py
$ python3 main.py
$ cat output.txt
test
```

長いのでここには書きませんが、実際に出力された main.pyを読んでみると、codecs.open を使用していることがわかります。

当然ながら、[python.lib.Codecs](http://api.haxe.org/python/lib/Codecs.html) はPython出力時にしか使用できませんので、注意が必要です。
（[sys.io.File](http://api.haxe.org/sys/io/File.html)はC++, PHP, nekoなどの他のプラットフォーム向けコンパイルも可能）


# Haxe/Pythonでライブラリを使用する

## Pythonの標準ライブラリを呼び出す

上記 codecs を利用する場合のように、Pythonの標準ライブラリのいくつかはそのまま利用可能です。
[Issue#2924](https://github.com/HaxeFoundation/haxe/pull/2924)より、現時点ではsys.netの一部とsys.dbの全ては未実装（いずれ実装予定）のようです。利用可能なものは[python.lib パッケージ](http://api.haxe.org/python/lib/)で確認できます。


## Haxeのライブラリを使用してPython出力する

[HtmlParser](http://lib.haxe.org/p/HtmlParser)というHaxe実装のHTMLパーサライブラリがあります。（たぶんpureな）Haxe実装なので、Haxeが対応しているプラットフォームならいずれにも出力することが出来るはずです。そう、もちろんPythonにも！

というわけでHaxeのライブラリをインストールして利用してみます。

```sh
$ haxelib install HtmlParser
```

```hx:Main.hx
import sys.io.File;

import htmlparser.HtmlDocument;

class Main {
  static public function main():Void {
    var html = new HtmlDocument(File.getContent("example.html"));
    var titles = html.find(">html>head>title");
    trace(titles[0].innerHTML);
  }
}
```

ライブラリ使用時はコンパイル時に-libオプションで使用するライブラリを指定します。

```sh
$ haxe -main Main -python main.py -lib HtmlParser
```

```html:example.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Title of Example</title>
  </head>
  <body>
    <h1>Example</h1>
  </body>
</html>
```

```sh
$ python3 main.py
Title of Example
```

HTMLをパースして、タイトルを取得できていることがわかります。

つまり、（pureな）Haxe実装のライブラリであればPython向けに利用することもできるし、その他のプラットフォームにも同じライブラリを利用することが出来ます。すごいね！
（もちろん、HTMLパーサぐらいは既にPythonで優秀なライブラリがいくつもありますが…）

# 課題とか

* Pythonの外部ライブラリを使用したいときはどうするの？（externして@:pythonImport？externがめんどくさそう…）