#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による動的メソッド実行
- メソッドを定義するメソッドの書き方
- クラスマクロの作成の仕方