HackがあればPHPでも型がつけられる!とか色々言っている割にインストールすらしてないありさまな状態から脱出すべく入門しました(´・_・`)
ちなみにHackというのはジェネリクスや返り値の型指定など、PHPのタイプヒンティングを強化したような機能をもっているFacebookが作った言語です。
詳しくは以下を参照すると良いと思います( ⁰⊖⁰)
Dockerで構築
いつものようにVagrantでやろうかなーと思ったのですが、 そろそろカジュアルにDockerを使えるようにならねばという気持ちもあったのでDockerで環境構築しました。(ちなみにhhvmはmacに対応していません。南無三)
ちょうど同じようなことを公開してくださっている方がいたので、 Docker で Hack - Qiitaの記事をベースに始めました。 が、月日が流れたせいかちょっとできなかったのでPrebuilt packages on Ubuntu 14.04 · facebook/hhvm Wiki · GitHubを参考に書きました。₍₍ (ง ˘ω˘ )ว ⁾⁾
もろもろは、https://github.com/matsu-chara/docker-hhvmに上げてあります。
ちなみに
docker -v
Docker version 1.5.0, build a8a31ef
です。
FROM ubuntu RUN apt-get update RUN apt-get install -y nginx RUN apt-get install -y software-properties-common RUN apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449 RUN add-apt-repository 'deb http://dl.hhvm.com/ubuntu trusty main' RUN apt-get update RUN apt-get install -y hhvm
具体的な手順は、 さきほどのDockerfileがあるディレクトリにsrcというコンテナと共有するためのディレクトリを作成しておいた状態で、
docker build -t chara/hhvm . docker run -i -t -d -v pwd/src:/home --name hhvm chara/hhvm /bin/bash docker attach hhvm
とすれば出来ます。attach後は何も表示されないのですが、エンターとか押せばプロンプトが表示されると思います。
これで
hhvm -v HipHop VM 3.7.1 (rel) Compiler: tags/HHVM-3.7.1-0-g111c76378ac29aa8f25e6bb3c5f15b628e6bbea1 Repo schema: be14a89778f35ca7f7dd4aca7fff0793e8ae3334
のようにできます。やったー₍₍ (ง ˘ω˘ )ว ⁾⁾
Hack
さて、type checkerを作動させるために.hhconfigという空ファイルがプロジェクトルートに存在する必要がありますので
cd /home touch .hhconfig
しましょう。 これで準備完了です。
<?hh function f(): int { return 'not an int'; } echo f() . "\n";
のようなintを返すと言っているのにstringを返している関数を持ったhello.hh
を書いて実行します。
> hhvm hello.hh
Fatal error: exception End_of_file
型エラーです!カタアンゼン!ヤッタ―!*1
ということで
<?hh function h(): string { return 'not an int'; } echo h() . "\n";
に変更したhello2.hh
を用意してhhvm hello2.hh
とすると実行できるようになりました。
ちなみに、hello.hh
でも、f
の呼び出しを行わなければ実行することが出来ます。関数の引数を受け取ったときと返り値を返すときに型チェックを実行時に見る仕組みのようです。
実行時の挙動に基づく検査ではなく実行前に型付けに矛盾がないかチェックしたい!という場合は、
hh_client
を実行すると裏でhh_serverを起動して、.hhconfig
以下に対して型チェックを行ってくれます。
hh_client /home/hello2.hh:3:10,10: Name already bound: f (Naming[2012]) /home/hello.hh:3:10,10: Previous definition is here
おっと、たしかに同じプロジェクトに同名の関数がありますね。 適当にhello2をg()とかに修正します。
hh_client /home/hello.hh:4:10,21: Invalid return type (Typing[4110]) /home/hello.hh:3:15,17: This is an int /home/hello.hh:4:10,21: It is incompatible with a string
おお!できました。この状態でも
hhvm hello.hh
は実行可能です。基本はhh_clientでチェックをするけど、だるいときはhhvmで実行しながらもデバッグできそうです。
実はなんか上手く行かなくて、
> hh_client logname: no login name Fatal error: exception End_of_file
とか言われてしまっていたのですが、suしたら治りました。たぶんuserを普通に作れば問題ないんだと思いますが開発用だしこれでいいかな・・・(´・_・`)
開始したサーバープロセスは
> hh_client stop
で停止します。
とりあえず入門なのでこの辺で終わります( ⁰⊖⁰)
参考文献
- Hack
- 新言語Hackで最強PHPerになろう! - Qiita
- Dockerで不要になったコンテナやイメージを削除する - @znz blog
- コンテナ内でのテータ管理 - Docker User Guide - Qiita
- 【Docker】 ホストとファイルを共有する - 子持ちプログラマーの日記
- Docker で Hack - Qiita
- Prebuilt packages on Ubuntu 14.04 · facebook/hhvm Wiki · GitHub
*1:実行時のチェックだけど・・・