我正在尝试创建一个宏"has_accessor_for",它接受一个符号,该符号用作它使用的内部对象( Accessorizer对象)的参数。我遇到的问题是,当多个模块执行has_accessors_for时,参数(作用域)最终停留在它被分配的最后一个值上。
我在define_method之前添加了一个puts,它显示它是scope1,然后是scope2...但在define_method中,它始终是scope2。我正在寻找一种基本上封装这个变量的方法,这样当它的第一个模块调用has_accessor_for时,任何时候my_wut被调用时,它都会被绑定到scope1……无论何时调用my_bleah,它都将被绑定到scope2。但是正如我所说的,现在,my_bleah和my_wut都绑定到作用域2--如果我在MyModel中更改includes的顺序,那么它们都将绑定到scope1。
class Accessorizer
  def initialize(record, scope)
    @record = record
    @scope = scope
  end
  def value_for(key)
    @record.send key
  end
end
module Magic
  def has_accessors_for(scope)
    accessors = {}
    puts "initial: #{scope}"
    define_method :get_value_for do |key|
      puts "inside method #{scope}"
      accessor.value_for key
    end
    define_method :accessor do
      accessors[:scope] ||= Accessorizer.new(self, scope)
    end
  end
end
module SomeAccessor
  extend Magic
  has_accessors_for :scope1
  def my_wut
    get_value_for :wut
  end
end
module SomeOtherAccessor
  extend Magic
  has_accessors_for :scope2
  def my_bleah
    get_value_for :bleah
  end
end
class MyModel
  include SomeAccessor
  include SomeOtherAccessor
  attr_accessor :wut, :bleah
end
m = MyModel.new
m.wut = 'wut'
m.bleah = 'bleah'
m.my_bleah
m.my_wut输出:
initial: scope1
initial: scope2
inside method scope2
inside method scope2发布于 2014-08-07 15:21:59
简而言之:问题不在于闭包。
长长的答案:
define_method :get_value_for do |key|
  puts "inside method #{scope}"
  accessor.value_for key
end在一个给定的类上,只能有一个名为get_value_for的方法-第二个定义将覆盖第一个定义。
这并不重要,因为您在两种情况下都调用了accessor,但是该方法遇到了相同问题-您定义了它两次,因此第二个定义覆盖了第一个定义,最后只有一个Accessorizer对象。
我认为你需要在这里重新考虑你的设计。
https://stackoverflow.com/questions/25175387
复制相似问题