🤖

attr_accessor的なものを再発明する

2021/12/30に公開

目的

attr_accessor みたいなメソッドってどうやって作られているのだろう?
という疑問から、attr_accessor_alias というアクセサメソッドを作ってみました。

ModuleとClassの関係

Class.superclass
=> Module

ModuleはClassクラスのsuperclassとなっています。

そのため、Module#hoge などのModuleクラスのインスタンスメソッドとして定義されたものはClass.new.hoge といった感じでClassクラスのインスタンスメソッドとして使用可能です。
なので、対象のメソッドはModuleクラスのインスタンスメソッドとして定義すれば良いでしょう。(Classクラスのインスタンスメソッドとしてでも可)

メソッドの作成

class Module
  def attr_accessor_alias(*attrs)
    attrs.each do |attr|
      define_method attr do
        instance_variable_get("@#{attr}")
      end

      define_method "#{attr}=" do |val|
        instance_variable_set("@#{attr}", val)
      end
    end
  end
end

適当なクラスを作成してみる

class MyClass
  # MyClassはModuleクラスを継承したClassクラスのインスタンスであるので
  # attr_accessor_aliasを呼び出し可能
  attr_accessor_alias :hoge, :fuga
end
[6] pry(main)> c = MyClass.new
=> #<MyClass:0x00007fd7418ae3d0>
[7] pry(main)> c.hoge
=> nil
[8] pry(main)> c.hoge = 30
=> 30
[9] pry(main)> c.fuga = 22
=> 22
[10] pry(main)> c
=> #<MyClass:0x00007fd7418ae3d0 @fuga=22, @hoge=30>
[11] pry(main)> 

うまくいきました。めでたし。

参考

  • メタプロRuby

Discussion