Arantium Maestum

プログラミング、囲碁、読書の話題

js_of_ocamlとduneでDOMオブジェクトを操作してみる

前回に続いてjs_of_ocamlとduneを使ってみる話。今回はJs_of_ocamlが用意しているDOM操作のAPIと構文を使う。

ディレクトリ構成は前回と同一:

.
├── dune
├── main.ml
└── main.html

main.htmlもまったく変わらず:

<html>
    <head>
        <script type="text/javascript" src="_build/default/main.bc.js"></script>
    </head>
    <body>
    </body>
</html>

main.ml:

open Js_of_ocaml

let () = Dom_html.window##alert (Js.string "Hello")

Dom_htmlにJavaScriptで取り扱えるおなじみのDOMオブジェクトが定義されている。今回はWindowオブジェクトのalertメソッドを使っている。

alertメソッドはOCamlではなくJSの文字列を期待している(そして両者はjs_of_ocamlを通していても違う)ので変換用にJs.stringという関数が用意されている。サンプルコードなどを眺めていると、これは多用されがちなのでlet js = Js.stringなどと短い名前に再束縛される事が多いようだ。

Js_of_ocamlはオブジェクトを多用している上にプリプロセッサを使ってそれらを扱うための構文を追加している。

具体的にはDom_html.window##alert##の部分である。

メソッド、プロパティへのアクセスや代入が以下の通りで可能:

(* メソッド呼び出し *)
obj##method x

(* プロパティへのアクセス *)
obj##.property

(* プロパティへの代入 *)
obj##.property := x

詳細はjs_of_ocamlを開発しているOcsigenのサイトを参照。

これら構文を扱えるようにduneファイルにも変更:

(executable
  (name main)
  (modes js)
  (preprocess (pps js_of_ocaml-ppx)))

js_of_ocaml-ppxというプリプロセッサを使う、という宣言をしている。

個人的に不思議なのは、Js_of_ocamlモジュールを使っているのにライブラリとしてduneに明示的に入れなくても大丈夫な点。(modes js)で自動的に入ってくる、という理解でいいのだろうか。

あとは前回どおりduneコマンドでビルド:

$ dune build ./main.bc.js

これでブラウザでmain.htmlを開くとすぐに"Hello"とアラートメッセージが表示される。

DOMオブジェクトを操作できるようになると一気にブラウザ上でできる事が増える。ただ、ぼちぼちDOMをいじるというのは正直最近のJSベストプラクティスからかけ離れている・・・。できれば多用しないでロジックはなるべく純粋なOCamlで完結させた方がいい気がする。