Я опоздал на эту вечеринку примерно на 3 года, но решил поделиться подходом, позволяющим относиться к внутреннему блоку как к настоящему блоку, а не как к простому старому аргументу.
Лучший известный мне способ сделать это — создать объект, который будет действовать как контекст привязки, и определить внешний блок как метод. Итак, если я перепишу исходный пример следующим образом без вызова instance_exec...
inner_proc = proc { puts "inner" }
outer_proc = proc { |*args, &inner_block|
puts *args
inner_block.call
puts "bar"
}
Мы можем определить outer_proc
как метод объекта.
scope_object = Object.new
scope_object.define_singleton_method :bound_proc, &outer_proc
Теперь вы можете вызывать scope_object.bound_proc
вместо вызова instance_exec
выше.
scope_object.bound_proc 1, 2, 3, &inner_proc
Ты получишь:
1
2
3
inner
bar
К сожалению, вы получите LocalJumpError, если попытаетесь выполнить yield внутри outer_proc
, а не inner_block.call
, я не совсем понимаю, почему. Если у кого-то есть такой ответ, мне было бы интересно.
person
Erick J
schedule
17.11.2016