Ruby

rubyでクラスマクロを作った

rubyでクラスマクロを作った

環境

ruby 2.4.1

概要

また、メタプログラミングです。
attr_accessorのようなクラスマクロをメタプログラミングRuby 第2版を見ながらrubyで組んだので、それの備忘録です。

クラスマクロとは

attr_accsessorのようなキーワードに見えるクラスメソッドの事です。
下に使用例を書きました。

class MyClass
  attr_accessor :test1
end

obj = MyClass.new
obj.test1 = "hoge"
puts obj.test1
出力
hoge

今回作成したクラスマクロ

attr_accessorはC言語でコーディングされていますが、今回はrubyで書いて
それに、ランダム性を持たせたattr_randomというクラスマクロを作成しました。

メタプログラミングの復習に良かったです。

ソースコード

module RandomAttributes
  def self.included(klass)
    klass.extend ClassMethods
  end

  module ClassMethods
   def attr_random(attribute)
       define_method "#{attribute}=" do |value|
         return false  if value.nil?
         return false  unless value.kind_of?(String)

         rand_val = value.split("").sort_by!{rand}
         instance_variable_set("@#{attribute}", rand_val.join)
       end

       define_method "#{attribute}" do
          instance_variable_get "@#{attribute}"
       end
    end
  end
end

class MyClass
  include RandomAttributes
  attr_random :test1
  attr_random :test2
  attr_random :test3
end

def check_attr_random
  obj = MyClass.new
  name = ["Tarou", "Saburou", "Kotarou"]
  obj.methods.grep(/test.*=/).each_with_index do |t, i|
    obj.send(t, name[i])
  end

  obj.methods.grep(/test[1-3]$/).each_with_index do |t, i|
    puts obj.send(t)
  end
end

check_attr_random
出力
Troua
oaruubS
uaKroto

※ ランダムなので出力は実行ごとに変わるので注意してください。

最後に

個人的に復習できたポイントについてまとめます。

  • self.includedによるフック処理
  • obj.sendによる動的メソッド実行
  • メソッドを定義するメソッドの書き方
  • クラスマクロの作成の仕方