我在Ruby中有一个DSL,它是这样工作的:
desc 'list all todos'
command :list do |c|
c.desc 'show todos in long form'
c.switch :l
c.action do |global,option,args|
# some code that's not relevant to this question
end
end
desc 'make a new todo'
command :new do |c|
# etc.
end一位开发人员建议我增强我的DSL,使其不需要将c传递给command块,因此不需要对其中的所有方法都使用c.;他可能暗示我可以使以下代码工作相同:
desc 'list all todos'
command :list do
desc 'show todos in long form'
switch :l
action do |global,option,args|
# some code that's not relevant to this question
end
end
desc 'make a new todo'
command :new do
# etc.
endcommand的代码如下所示
def command(*names)
command = make_command_object(..)
yield command
end我尝试了几种方法,但都无法使其正常工作;我不知道如何将command块中代码的上下文/绑定更改为不同于默认设置。
如果这是可能的,我会怎么做,你有什么想法吗?
发布于 2011-05-02 07:06:32
class CommandDSL
def self.call(&blk)
# Create a new CommandDSL instance, and instance_eval the block to it
instance = new
instance.instance_eval(&blk)
# Now return all of the set instance variables as a Hash
instance.instance_variables.inject({}) { |result_hash, instance_variable|
result_hash[instance_variable] = instance.instance_variable_get(instance_variable)
result_hash # Gotta have the block return the result_hash
}
end
def desc(str); @desc = str; end
def switch(sym); @switch = sym; end
def action(&blk); @action = blk; end
end
def command(name, &blk)
values_set_within_dsl = CommandDSL.call(&blk)
# INSERT CODE HERE
p name
p values_set_within_dsl
end
command :list do
desc 'show todos in long form'
switch :l
action do |global,option,args|
# some code that's not relevant to this question
end
end将打印:
:list
{:@desc=>"show todos in long form", :@switch=>:l, :@action=>#<Proc:0x2392830@C:/Users/Ryguy/Desktop/tesdt.rb:38>}https://stackoverflow.com/questions/5851127
复制相似问题