使用此方法可以动态地将args发送到对象:
module DSL
def update object, *args, &block
updated_object = object.send *args
# then, some stuff with the updated object and the block
end
end
可以使用以下代码,例如:
include DSL
# equivalent to: Array.new 3, :foo
update Array, :new, 3, :foo do
# updated object => [:foo, :foo, :foo]
# some stuff
end
或者如:
# equivalent to: [:foo, :foo, :foo].size
update [:foo, :foo, :foo], :size do
# updated object => 3
# some stuff
end
但是我们如何才能更新此update
方法的内容以处理块,例如:
[:foo, :bar].select {|a| a == :foo }
我考虑将块转换为proc,例如:
update [:foo, :bar], :select, &:foo.method(:==) do
# ...
end
但是,因为同一个方法不能处理多个块,所以引发了这个异常:
SyntaxError:既包含块arg又包含实际块
有没有一种优雅的方法来解决这个问题?
答案 0 :(得分:1)
我认为你已经超越了这个,但无论如何,这是一个想法:
你可以将常规proc传递给你的update
方法,然后对最后一个参数进行特殊处理,这是一个proc。
module DSL
def update object, *args, &block
updated_object = if args.last.is_a? Proc
proc = args.pop
object.send *args, &proc
else
object.send *args
end
yield updated_object
end
end
extend DSL
update [:foo, :bar], :select, ->(a) { a == :foo } do |obj|
puts "selected object: #{obj}"
end
# >> selected object: [:foo]