Tambourine作業メモ

主にスキル習得のためにやった作業のメモ。他人には基本的に無用のものです。

attr_accessorを自分で実装する

自作クラスでデータを保持しようとしていて半角カナが入ってきて発狂し、絶叫し、半角カナ絶対殺すマンが覚醒した。

といっても、Rubyで半角カナを全角カナに変換するのはとても簡単。NKFを使う。

> irb
irb(main):001:0> require 'nkf'
=> true
irb(main):002:0> a = "いささかプギャーな気分"
=> "いささかプギャーな気分"
irb(main):003:0> NKF.nkf("-Xw", a)
=> "いささかプギャーな気分"

これをセッターに組み込めばいい

require 'nkf'

class MyRecord
  @rec = ""
  
  attr_reader :rec
  
  def rec=(str)
    @rec = NKF.nkf("-Xw", str)
  end
end

r = MyRecord.new

r.rec = "いささかプギャーな気分"

p r.rec # => "いささかプギャーな気分"

問題ない。しかし、フィールドは1つではないかもしれない。 3つあったらこうなるだろう。

class MyRecord
  @rec1 = ""
  @rec2 = ""
  @rec3 = ""
  
  attr_reader :rec1, :rec2, :rec3
  
  def rec1=(str)
    @rec1 = NKF.nkf("-Xw", str)
  end
  
  def rec2=(str)
    @rec2 = NKF.nkf("-Xw", str)
  end
  
  def rec3=(str)
    @rec3 = NKF.nkf("-Xw", str)
  end
end

半角カナ絶対殺すマンは転生し、絶対DRY星人として蘇った。

さて、どうするか。こんな感じに出来ればいいのだろう。

class MyRecord
  @rec1 = ""
  @rec2 = ""
  @rec3 = ""
  
  my_attr :rec1, :rec2, :rec3
end

my_attrはMyRedordクラスのクラスメソッドとして定義してやればいい。 Rubyist人生で初めてinstance_variable_setを使った。

require 'nkf'

class MyRecord
  def self.my_attr(*name)
    attr_reader *name
    name.each do |n|
      define_method("#{n.to_s}=") do |str|
        instance_variable_set(
          "@#{n.to_s}".to_sym,
          NKF.nkf("-Xw", str)
        )
      end
    end
  end
  
  @rec1 = ""
  @rec2 = ""
  @rec3 = ""
    
  my_attr :rec1, :rec2, :rec3
end

r = MyRecord.new

r.rec3 = "いささかプギャーな気分"

p r.rec3 # => "いささかプギャーな気分"