我想制作一个简单的DSL,我可以将一堆方法传递给一个块,依靠self作为隐式接收器。所以基本上你可以打电话给'说'关于这个类对象的方法,传递它的事情要说'作为块中的方法。最后一行返回[' Maria']。我想知道这是否是创建DSL的良好编程实践,以及这种方法是否存在任何问题。
class SaySomething
def initialize
@said = []
end
def hey(name)
@said << name
end
def say(&block)
instance_eval(&block)
end
end
a = SaySomething.new
name = 'Maria'
a.say do
hey(name)
end
a.instance_eval { p @said } #=> produces ['Maria']
答案 0 :(得分:1)
我可能会添加一个attr_accessor :said
,然后用
a.said
#=> ['Maria']
除此之外,您的代码对我来说很好。如果你想在Ruby中学习更多关于元编程的知识,我可以推荐这本书&#34; Eloquent Ruby&#34;。
答案 1 :(得分:0)
这种方法的唯一问题是任何类变量都会与块中的变量碰撞。通常的方法是提供实例评估,但也允许用户将类指定为参数作为后退。
class Test
def test; "hello"; end
def say(&b)
if b.arity == 1
b.call(self)
else
instance_eval &b
end
end
end
t = Test.new
test = "fred"
t.say { p test } # "fred"
t.say { |t| p t.test } # "hello"