crystalを少し触ったので、ここに書いとく
##環境
crystal 0.25.1
Zorin OS 12.3
##概要
rubyやってるからついでにcrystalもやってみようと思って触ってきました。
多分今後、crystalに触れる事は少なくなるので、ここに感じた事など書き留めておきます。
crystalとは
ruby風の文法で記述できる静的型付け言語です。
LLVMを使用しており高速であり、ベンチマークテストでは、よくTOP10に食い込んでます。
crystalの基本文法はこのサイトで、学習できます。
もっと詳しく知りたい人は公式サイトを見てください。
型の指定
静的型付けだけあって型はしっかりかけます。
下の例では、引数であるnumにInt32型を指定し、渡す値もInt32を使っています。
def disp_num(num : Int32)
puts num
end
disp_num(2_i32)
2
ただし強制ではないので、rubyのようにもかけます。
この場合、Int32で足りる数値範囲ならデフォルトでInt32になります。
def disp_num(num)
puts num
end
disp_num(2)
2
メタプログラミング
静的型付けの言語でもメタプログラミングができるのだと驚きました。
crystalはmacroを使用することでコンパイル中にastを返却しメタプログラミングを可能にします。
下に簡単な例を記載しました。
macro meta_test(name, num)
def {{name}}
{{num}}
end
end
meta_test output_num, 100
p output_num
100
Hook処理なども多数あるので、良し悪しは置いといてゴーストメソッドなどのテクニックも使えるでしょう。
下記の例では、macro method_missingがhoge, fugaなどの存在しないメソッドに対して動作します。
macro method_missing(call)
print "存在しないメソッドが呼ばれました", '\n'
print "名前:", {{call.name.id.stringify}}, "引数の数", {{call.args.size}}, '\n'
end
hoge 100, 200
fuga
存在しないメソッドが呼ばれました
名前:hoge引数の数2
存在しないメソッドが呼ばれました
名前:fuga引数の数0
ポインタ
crystalでは、pointerofメソッドを使って参照渡しが可能です。
下記の例では、numに100を代入した後に参照渡しを使い200に上書きしています。
def update_num(ptr, value)
ptr.value = value
end
num = 100
update_num(pointerof(num), 200)
p num
200
おまけ
他にも色々面白い事ができるので、ちょっとだけ紹介。
crystalとcは仲良し
記述量が多くなるので省略しますが、crystalはrubyにはないenumや構造体が使えます。
また、Cのlibrayをcrystal内から呼び出すことも可能です。
詳しくは、C bindingsを読んでください。
数値の表記
crystalは数値を見やすいようにアンダースコアで区切ることができます。
下記のような感じで使えます。
puts 1_0_0_0_0
10000
電話番号とか郵便番号とかに使うとコードの可読性があがるでしょう。
Go言語っぽいswitch文
_をつけて、値をなくすのはGoではよくある手法ですがcrystalのswitch文でも、それが可能です。
case {1, 3}
when {1, _} then puts "左が1です"
when {_, 2} then puts "右が2です"
when {1, 5} then puts "左1で右が5です"
end
左が1です
こんな感じでcrystal独自のものが結構あって面白いです。
感想
ruby3.0が静的型付けを方向性の1つとして指し示していますが、crystalみたいな
感じになるのかなと個人的に思いました。
rubyをやっている人は、文法が似ているのですぐにチュートリアルが終わるかと思います。
使える言語は増えれば増えるほど楽しいので、是非crystalに挑戦してみてください。