自定义attr_reader以执行属性的延迟实例化

JP.*_*JP. 5 ruby accessor

(大编辑,我在那里得到了一部分...)我一直在乱砍,我想出了一个方法来指定在读取属性之前需要完成的事情:

class Class
  def attr_reader(*params)
    if block_given?
      params.each do |sym|
        define_method(sym) do
          yield
          self.instance_variable_get("@#{sym}")
        end
      end
    else
      params.each do |sym|
        attr sym
      end
    end
  end
end

class Test
  attr_reader :normal
  attr_reader(:jp,:nope) { changethings if @nope.nil? }

  def initialize
    @normal = "Normal"
    @jp = "JP"
    @done = false
  end

  def changethings
    p "doing"
    @jp = "Haha!"
    @nope = "poop"
  end

end

j = Test.new

p j.normal
p j.jp
Run Code Online (Sandbox Code Playgroud)

但是changethings没有被认为是一种方法 - 任何人都有任何想法?

mck*_*eed 4

您需要在实例的上下文中评估该块。yield默认情况下将在其本机上下文中对其进行评估。

class Class
  def attr_reader(*params, &blk)
    if block_given?
      params.each do |sym|
        define_method(sym) do
          self.instance_eval(&blk)
          self.instance_variable_get("@#{sym}")
        end
      end
    else
      params.each do |sym|
        attr sym
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)