src/compiler
以下を読んでいると、ちょいちょいrecord
ってでてくるけど、docになかったので調べてみた。
class String
...
record ToU64Info, value, negative, invalid
...
end
実体はマクロでsrc/macros.cr
に定義されている。
macro record(name, *fields)
struct {{name.id}}
getter {{*fields}}
def initialize({{ *fields.map { |field| "@#{field.id}".id } }})
end
{{yield}}
def clone
{{name.id}}.new({{ *fields.map { |field| "@#{field.id}.clone".id } }})
end
end
end
getter
とclone
つきのstruct
をそのクラス内に定義してくれる。
class My
record MyRecord, key, value
def initialize(@key, @value)
end
def record
MyRecord.new @key, @value
end
end
my = My.new "hoge", 10
puts my.record
#=> My::MyRecord(@key="hoge", @value=10)
puts typeof(my.record)
#=> My::MyRecord
puts my.record.key
#=> hoge
ブロックもとることができ、struct
の文脈でyieldしてくれる。
class My
record MyRecord, key, value do
def to_hash
hash = {} of typeof(@key) => typeof(@value)
hash[@key] = @value
hash
end
end
def initialize(@key, @value)
end
def record
MyRecord.new @key, @value
end
end
my = My.new "hoge", 10
puts my.record.to_hash
#=> {"hoge" => 10}
あれ、マクロだとブロック内でdef
できるんだ。。