前に Crystal の記事を書いて、
このスライドの中で、
と書いたんですが、現在は条件分岐中のメソッド定義はエラーになるようになっています。
if true def hoge end end
% crystal hoge.cr Error in ./hoge.cr:2: can't declare def dynamically def hoge ^~~~
これは、次の Issue で変更されたのですが、
"Seen here" で私のスライドが参照されているという…。しかもスライド公開した翌日に。 Qiita の Crystal の日本語の記事も読んでるみたいだし、Crystal 作者さんすごいな。
その後、Crystal を触ってて気づいたことなど:
インスタンス変数の型
class A def hoge @str = "hoge" @str + "fuga" end end A.new.hoge
これはコンパイル時にエラーになります。
/tmp% crystal hoge.cr Error in ./hoge.cr:8: instantiating 'A#hoge()' A.new.hoge ^~~~ in ./hoge.cr:4: undefined method '+' for Nil (compile-time type is String?) @str + "fuga" ^ ================================================================================ Error: instance variable '@str' of A was not initialized in all of the 'initialize' methods, rendering it nilable Specifically in these ones:
@str
は明らかに文字列なのですが、initialize
内で初期化されていないインスタンス変数は nil の値を取りうるものとして扱われるためです。
initialize
で初期化するか型を指定すれば問題ありません。
class A def initialize @str = "hoge" end def hoge @str + "fuga" end end A.new.hoge
class A def initialize @str :: String end def hoge @str = "hoge" @str + "fuga" end end A.new.hoge
.crystal
ディレクトリ
crystal はコンパイル時にカレントディレクトリに .crystal
というディレクトリを作ります。ソースコードの場所にかかわらず、カレントディレクトリに作ります。
気がつくとあちこちに .crystal
が出来てて驚きます。
環境変数 CRYSTAL_CACHE_DIR
が設定されていると、カレントディレクトリではなくその値のディレクトリを使用するようです。
自分は $HOME/.crystal
を設定してあります。
シグナル処理が効かない!
次は INT シグナルを無視するプログラムですが、
Signal::INT.ignore sleep 99999
実行すると Ctrl-C で止まってしまいます。
% crystal hoge.cr ^C %
ちょっと悩んだのですが、解決しました。
スクリプト言語と違って Crystal はコンパイル言語なので、crystal hgge.cr
として実行した時は、実際にはコンパイルして作成されたプログラムを子プロセスとして実行しています。
なので、SIGINT で死んだのは親プロセスの crystal で hoge.cr からコンパイルされたプログラムはちゃんと SIGINT でも死なずに動いていました。
% crystal hoge.cr ^C % ps -fe | grep hoge tommy 5993 2190 0 00:01 pts/1 00:00:00 /home/tommy/.crystal/crystal-run-hoge.tmp tommy 5998 3148 0 00:01 pts/1 00:00:00 grep hoge % kill -INT 5993 % ps -fe | grep hoge tommy 5993 2190 0 00:01 pts/1 00:00:00 /home/tommy/.crystal/crystal-run-hoge.tmp tommy 6000 3148 0 00:01 pts/1 00:00:00 grep hoge % kill 5993 % ps -fe | grep hoge tommy 6002 3148 0 00:01 pts/1 00:00:00 grep hoge %
わかってみたら、なんだそんなことか… ってオチでした。