Crystalのmacro紹介 "record"
この記事は、 Crystal Advent Calendar 2017 の5日目の記事です。
crystalには便利なmacroがあります。macroを使えば、記述量も削減でき表現力も向上します。しかし、ただcrystalを書いているだけでは、なかなかそれらのmacroに出会うことができません。
ということで、アドベント・カレンダーの日数稼ぎも兼ねて、macroの紹介をしたいと思います。
そもそも「macroってなんだ」という場合は、下記の本家docsを参照してください。
今回は、 record
を紹介します。
record
crystal-lang.org/api - Top Level Namespace - record
Struct
を簡単に記述できるmacroです。シグネチャは以下です。
macro record(name, *properties)
通常、Struct
の定義はこうです。
# Structの定義 struct User1 property name : String property age : Int32 def initialize(@name, @age) end end user1 = User1.new "Taro", 30 p user1 # => User(@age=30, @name="Taro") p user1.name # => "Taro" p user1.age # => 30
これをmacroのrecord
を使うとこうなります。
# Structの定義 record User2, name : String, age : Int32 user2 = User2.new "Taro", 30 p user2 # => User(@age=30, @name="Taro") p user2.name # => "Taro" p user2.age # => 30
1行で定義が書けてしまいました。
メソッドを定義する場合は、blockを用います。
# Structの定義 record User3, name : String, age : Int32 do def greeting "Hello!" end end user3 = User3.new "Taro", 30 p user3 # => User(@age=30, @name="Taro") p user3.name # => "Taro" p user3.age # => 30 p user3.greeting # => "Hello!"
propertyの初期値も設定できます。
# Structの定義 record User4, name : String = "Taro", age : Int32 = 30 user4 = User4.new p user4 # => User(@age=30, @name="Taro") p user4.name # => "Taro" p user4.age # => 30
初期値から、型の推論も行ってくれます。
# Structの定義 record User5, name = "Taro", age = 30 user5 = User5.new p user5 # => User(@age=30, @name="Taro") p user5.name # => "Taro" p user5.age # => 30
ちょっとしたStruct
なら、record
を使うとスッキリ書けますね。
ぜひ使ってみてください。