如何创建自然变量分配

时间:2011-06-28 00:40:42

标签: ruby dsl

我正在开发一个相当简单的DSL,并希望更自然地声明和分配变量。

GlobalMemory.init {
  val1 5
  val2 "some string"
}

这适用于运行DSL的简单VM。这适用于此代码

class GlobalMemory
  include Singleton

  def self.init &blk
    GlobalMemory.instance.allocate &blk
  end

  def method_missing sym,*args, &blk
    @segments[sym]=args[0]
  end

  def allocate &blk
    self.instance_eval &blk
  end
end

有没有办法允许val1=5(and val1 = 5)?当我尝试这样做时,method_missing不会触发,也不会出现错误消息。

2 个答案:

答案 0 :(得分:1)

如果您执行以下操作,它将按原样运行:

GlobalMemory.init {
    self.val3 = 'value'
}

否则它与本地变量声明无法区分。我想更好的方法是使用一个块参数并编写你的init方法:

GlobalMemory.init { |g|
    g.val1 5
    g.val2 "some string"
    g.val3 = 'yeah'
}

我试图使用#local_variables来使var1 =解决方案工作时有点乱,但我最接近的就是:

class Foo
    def initialize(&bl)
        @data = {}
        b = yield self
        still_to_assign = eval('local_variables', b) - eval('local_variables', bl)
        still_to_assign.each { |v| r = eval(v,b); @data[v] = r }
    end
end

Foo.new {
    one = 1
    two = 2
    three = 3
    binding
}

如您所见,它要求您在块的末尾返回绑定对象。它还存在一些已经在块之前声明的变量的问题。也许有人可以建议一个更好的方法来做到这一点?

答案 1 :(得分:1)

我认为不可能像内部DSL那样干净利落地进行这项工作