define_method ってなんぞや

railsのプラグインを覗いてたら、eval系メソッドがもっさり出てきてわけのわからないことになったので、色々復習。

まずはdefine_method。

インスタンスメソッド name を定義します。

ブロックを与えた場合、定義したメソッドの実行時にブロックがレシーバクラスのインスタンスの上で Object#instance_eval されます。

instance method Module#define_method

#!/usr/bin/env ruby
module Hoge
  def define (bar)
    define_method("#{bar}=") do |value|
      @val = value.reverse    
    end
    define_method("#{bar}") do 
      @val
    end
  end
end

class TestClass
  extend Hoge
  define :foo
end

test = TestClass.new
test.foo = "hoge"
puts test.foo # >> egoh

メソッド名通り、メソッドを定義する。
attr_accessor とかこういう実装なんだろうか。

ちなみにprivateメソッドなので、インスタンスからの呼び出しはできない

class ErrorTest
  include Hoge
end

err = ErrorTest.new
err.define :bar
err.bar = ''
# ~> -:4:in `define': undefined method `define_method' for #<ErrorTest:0x269d0> (NoMethodError)

なんかごにょごにょすると、インスタンスから渡した値でメソッドが作れそう。
まあ、今回はここまで。