可变范围干扰Ruby中的DSL

时间:2011-05-02 09:42:18

标签: ruby

module Typecast
  class DSL
    def self.call(&blk)
      new.instance_eval(&blk)
    end
    def new_age(val)
      p val
    end
  end

  def typecast(&blk)
    DSL.call(&blk)
  end
  private :typecast
end

class Person
  include Typecast
  def age=(new_age)
    typecast do
      new_age :integer
    end
  end
end

Person.new.age = 10

# test.rb:33: syntax error, unexpected ':', expecting keyword_end
#       new_age :integer

Ruby返回此错误,因为它知道new_age是方法参数中定义的局部变量。所以当我将Person类更改为:

class Person
  include Typecast
  def age=(new_val)
    typecast do
      new_age :integer
    end
  end
end

Ruby现在返回预期的:integer

我的问题是,如何阻止局部变量干扰instance_eval块?

1 个答案:

答案 0 :(得分:0)

如果变量和具有相同名称的方法都存在于同一范围内,则消除歧义的方法是澄清接收者。在这种情况下,您希望接收器为self

class Person
  include Typecast
  def age=(new_age)
    typecast do
      self.new_age :integer    # Avoids ambiguity because we used an
    end                        # explicit receiver.
  end
end

Person.new.age = 10
# => :integer
# => 10