u16suzuの blog

日々学んだことのメモブログです。

Rubyのメタプログラミングメモ

Classをインスタンス化する時にHashで渡した値でInitializeするクラスのテンプレート

class Person
  attr_accessor :name, :age, :address

  def initialize( hash={})
    if block_given?
      yield( self )
    else
      hash.each do |k, v|
        public_send("#{k}=", v) if respond_to?("#{k}=")
      end
    end
  end

  def to_s
    instance_variables.map do |ivar|
      value = self.send( ivar.to_s.tr("@", ""))
      "#{ivar}: #{value}"
    end.join(", ")
  end
end

p1 = Person.new({name: "taro", age: 20, address: 'tokyo'})
puts p1

p2 = Person.new do |f|
  f.name = "jiro"
  f.age  = 30
  f.address = "tokyo"
end
puts p2

class Man < Person
end

p3 = Man.new do |m|
  m.name ="saburo"
  m.age = 30
  m.address = "yokohama"
end
puts p3

p4 = Man.new({name: "shiro", age: 33, address: "oosaka"})
puts p4

クラスマクロ

  • 例外用のクラスマクロを定義した親クラスのテンプレート
class ExceptionBase < StandardError
  @_code

  def self.code(code=nil) # 引数がnilの時はgetter, nilでない時はsetterになる
    @_code ||= code
  end

  def code
    self.class.instance_variable_get("@_code")
  end
end

class NotFoundException < ExceptionBase
  code 404
end

class ForbiddenException < ExceptionBase
  code 403
end

p NotFoundException.code # => 404
p NotFoundException.new.code #=> 404

p ForbiddenException.code # => 403
p ForbiddenException.new.code # => 403

後で読む