我不确定这是否可以在Ruby中使用,但是如果有人知道一个好的解决方案。
我想更改块的结构,用其他代码结构替换其中的特定节点。很像宏。
例如,假设我有一个未评估的代码块
some_method do
foo
bar
end
然后我将some_method定义为
def some_method(&block)
...
end
在some_method中,我真的想将块中的“bar”替换为其他内容,例如:与巴兹。
我想更换w / o评估块,因为最终我将块传递到其他地方。
可行?还是不?
我可以想到相当复杂的答案:例如我可以通过一个额外的闭包来传递块,它定义了bar的替换,并且在计算bar时使用method_missing和continuation来替换bar和baz。但有更简单的方法吗?
感谢。
答案 0 :(得分:0)
Ruby没有动态作用域并且没有宏,所以除非你将块包装在以bar
作为参数的函数中,并传递该函数,我认为你不能替代这样的代码。您当然可以使用eval
,但我不推荐它=)
答案 1 :(得分:0)
这是我能想到的最简单的方法:
class Base
def some_method(&block)
self.instance_eval(&block)
end
def foo; puts 'foo'; end
def bar; puts 'bar'; end
end
class Replacement < Base
def foo; puts 'baz'; end
end
Base.new.some_method do
foo
bar
end
Replacement.new.some_method do
foo
bar
end
输出:
foo
bar
baz
bar
答案 2 :(得分:0)
别名和Procs帮助吗?
def foo; p 'foo'; end
def bar; p 'bar'; end
def sm(&block)
@@Block = Proc.new {
alias :oldbar :bar
def bar; p 'baz'; end #redefine
block.call
alias :bar :oldbar #restore
}
yield #prints foo,bar
end
sm do
foo
bar
end
def later(&block)
yield
end
def delayedEx
later { @@Block.call}
end
delayedEx #prints foo,baz
bar #prints bar (unchanged)
这会打印“foo bar foo baz bar”,即:bar
在块中执行不同的操作,但保留其原始行为。
答案 3 :(得分:-1)
def some_method(a_proc=Proc.new{puts "Bar"}, &block)
a_proc.call
yield
end
p1 = Proc.new{puts "Baz"}
some_method{puts "a block"}
some_method(p1){puts "a block"}