M
Michel Demazure
A meta-programming question. More precisely a scoping problem.
In short, is there a ruby way to execute a parameter-less block with a
given receiver ?
Here below my example : I am manipulating a pattern of rectangular boxes
in a plane, with a tree structure given by enclosure, and want to
describe them by a convenient DSL. I am keeping some parameters from the
real code to give a flavor of the example.
class Box
HORIZ = 1
VERT = 2
FIXED = 4
ADJUST = 8
def initialize(enclosing, flag, columns = [], height = 0)
@enclosing = enclosing
enclosing << self if enclosing
@enclosed = []
...
end
def <<(other)
@enclosed << other
end
def box(params = {}, &block)
newbox = Box.new(self, params[pts], params[:colums] || [],
params[:height] || 0)
block.call(newbox) if block
newbox
end
.....
end # class box
# duplication, part of the problem
def main_box(params ={}, &block)
newbox = Box.new(nil, params[pts], params[:colums] || [],
params[:height] || 0)
block.call(newbox) if block
newbox
end
big_box = main_box pts => VERT do |s|
s.box pts => HORIZ, :colums => [1,2,3,4,5,6,7,8,9], :height => 10
s.box pts => HORIZ do |b|
b.box pts => VERT, :colums => [7,8,9], :height => 90
b.box pts => VERT do |z|
z.box pts => HORIZ | ADJUST, :colums => [1,2,3,4,5,6]
z.box pts => HORIZ do |y|
y.box pts => VERT | FIXED, :colums => [4,5,6], :height => 70
y.box pts => VERT do |x|
x.box pts => HORIZ| FIXED, :colums => [1,2,3], :height => 20
x.box pts => HORIZ | ADJUST,:colums => [1,2,3]
x.box pts => HORIZ | FIXED, :colums => [1,2,3], :height =>35
end
end
end
end
end
The local variables in the blocks could be all the same, and are useless
to the DSL, but they seem necessary to secure the scopes. My question is
: is there a way to write the method 'box' so that it accepts the
simplified DSL without variables :
... box params do
box params do
Apologies for my English.
Michel Demazure
In short, is there a ruby way to execute a parameter-less block with a
given receiver ?
Here below my example : I am manipulating a pattern of rectangular boxes
in a plane, with a tree structure given by enclosure, and want to
describe them by a convenient DSL. I am keeping some parameters from the
real code to give a flavor of the example.
class Box
HORIZ = 1
VERT = 2
FIXED = 4
ADJUST = 8
def initialize(enclosing, flag, columns = [], height = 0)
@enclosing = enclosing
enclosing << self if enclosing
@enclosed = []
...
end
def <<(other)
@enclosed << other
end
def box(params = {}, &block)
newbox = Box.new(self, params[pts], params[:colums] || [],
params[:height] || 0)
block.call(newbox) if block
newbox
end
.....
end # class box
# duplication, part of the problem
def main_box(params ={}, &block)
newbox = Box.new(nil, params[pts], params[:colums] || [],
params[:height] || 0)
block.call(newbox) if block
newbox
end
big_box = main_box pts => VERT do |s|
s.box pts => HORIZ, :colums => [1,2,3,4,5,6,7,8,9], :height => 10
s.box pts => HORIZ do |b|
b.box pts => VERT, :colums => [7,8,9], :height => 90
b.box pts => VERT do |z|
z.box pts => HORIZ | ADJUST, :colums => [1,2,3,4,5,6]
z.box pts => HORIZ do |y|
y.box pts => VERT | FIXED, :colums => [4,5,6], :height => 70
y.box pts => VERT do |x|
x.box pts => HORIZ| FIXED, :colums => [1,2,3], :height => 20
x.box pts => HORIZ | ADJUST,:colums => [1,2,3]
x.box pts => HORIZ | FIXED, :colums => [1,2,3], :height =>35
end
end
end
end
end
The local variables in the blocks could be all the same, and are useless
to the DSL, but they seem necessary to secure the scopes. My question is
: is there a way to write the method 'box' so that it accepts the
simplified DSL without variables :
... box params do
box params do
Apologies for my English.
Michel Demazure