开发者

How to create natural variable allocation

I am working on a fairly simple DSL and would like to be declare and allocate variables more naturally.

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

This is for a simple VM that runs the DSL. This works just fine for this code

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

Is there a way to allow val1=5(and val1 = 5)? When I try that, method_missing doesn't trigger and no error messages occur.


It will work as-is if you do something like:

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

Otherwise it's indistinguishable from a local variable declaration. I guess the nicer way to do it would be to have a block parameter and write your init method like this:

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

I messed around a bit with trying to get the var1= solution working using #local_variables, but the closest I could come is this:

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
}

As you can see, it requires you to return a binding object at the end of your block. It also has some issues with variables that have already been declared prior to the block. Maybe someone can suggest a better way to do this?


I don't think it is possible to do this cleanly as an internal DSL

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜