Crystalのmacro紹介 "delegate"
この記事は、 Crystal Advent Calendar 2017 の7日目の記事です。
crystalには便利なmacroがあります。macroを使えば、記述量も削減でき表現力も向上します。しかし、ただcrystalを書いているだけでは、なかなかそれらのmacroに出会うことができません。
ということで、アドベント・カレンダーの日数稼ぎも兼ねて、macroの紹介をしたいと思います。
そもそも「macroってなんだ」という場合は、下記の本家docsを参照してください。
今回は、 delegate
を紹介します。
delegate
crystal-lang.org/api - Object - delegate
fieldのオブジェクトに処理を委譲させます。シグネチャは以下です。
macro delegate(*methods, to object)
通常、メソッドの委譲は、以下のように行います。
class User def initialize(@name : String, @age : Int32) end def greeting "Hi, my name is #{@name}." end end class PremiumUser def initialize(name : String, age : Int32) @user = User.new(name, age) end # オブジェクトに処理を委譲 def greeting @user.greeting end end premium_user = PremiumUser.new "Taro", 30 p premium_user.greeting # => "Hi, my name is Taro."
これをmacroのdelegate
を使うとこうなります。
class User def initialize(@name : String, @age : Int32) end def greeting "Hi, my name is #{@name}." end end class PremiumUser def initialize(name : String, age : Int32) @user = User.new(name, age) end # オブジェクトに処理を委譲するmacro delegate greeting, to: @user end premium_user = PremiumUser.new "Taro", 30 p premium_user.greeting # => "Hi, my name is Taro."
delegete {メソッド名}, to: {委譲先オブジェクト名}
として、メソッドを委譲先オブジェクトに任せます。delegete A to B
のような英語風味なところも良いですね。
ぜひ使ってみてください。