LoginSignup
2
1

More than 5 years have passed since last update.

crystalの`record`マクロとは

Last updated at Posted at 2015-06-27

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

gettercloneつきの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できるんだ。。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1