Feature #18815
openinstance_{eval,exec} vs Proc#>>
Description
measure = proc { p "self=#{self}"; size }
multiply = proc { '*' * _1 }
'test'.instance_eval(&measure)
# "self=test"
# => 4
'test'.instance_eval(&measure >> multiply)
# "self=main"
# NameError (undefined local variable or method `size' for main:Object)
So, Proc#>>
produces a proc which is not suitable for instance_eval
/instance_exec
. The same as the "naive" implementation:
# Naive sequence
sequence = proc { measure.call.then(&multiply) }
...but is it possible to make the combination to behave like the first proc is not wrapped into an additional layer of indirection?.. Intuitively, it shouldn't be completely impossible.
# What I meant actually:
intended = proc { size.then(&multilpy) }
"test".instance_eval(&intended)
# => "****"
The example is invented, the question is "whether this should work", not "how to solve this task with another approach".
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
- Is duplicate of Bug #18067: Composite procs with `instance_exec` aren't executed within the context of the receiver added
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
Updated by zverok (Victor Shepelev) over 2 years ago
@jeremyevans0 (Jeremy Evans) I don't think it is a "bug", but maybe a nice feature to have (composite procs being a bit smarter than just a really thin syntax sugar over what you could've done manually). The realistic case I have is a constant with definitions of how to handle some huge list of parameters, it might look like that:
FLATTEN = -> { [*_1] }
IDENTITY = -> { _1 }
DATE = -> { Date.parse(_1) }
TRANSFORMATIONS = {
param1: FLATTEN,
param2: FLATTEN,
param3: IDENTITY,
# ....
}
...and then, some processing is more complicated and depends on current class' context:
param4: -> { allowed?(:something) ? _1 : DEFAULT }
...now, if param4
should also be flattened before handling, I was happy I can write
param4: FLATTEN >> -> { allowed?(:something) ? _1 : DEFAULT }
...until I understood it wouldn't work :)
Obviously, I can (and did)
param4: -> { allowed?(:something) ? FLATTEN.(_1) : DEFAULT }
...but the >>
version looked much more clear, especially in big params list, so you can clearly read: this is flattened, this is flattened and then also post-processed.
Updated by jeremyevans0 (Jeremy Evans) over 2 years ago
- Tracker changed from Bug to Feature
- Backport deleted (
2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN)
zverok (Victor Shepelev) wrote in #note-3:
@jeremyevans0 (Jeremy Evans) I don't think it is a "bug", but maybe a nice feature to have
That makes sense. Switching to feature request.