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
精彩评论