| Here is some input with why it is beneficial to have an eval() function. Say you make a deferred call to get information (secret lookup, or some lookup from some cloud service) and the information is more than what you actually want - say you get a hash/ structure back, and you need to a) dig out a value, or b) that you get an array back and you want to filter certain things out, or you get a hash back, and you c) need to use that to call another function that takes two values that both come from the obtained hash. (a) Get value from deferred result
# using only Deferred |
Deferred('get', [Deferred('some_lookup', ['some_key']), 'subkey']) |
# using eval |
Deferred('eval', ["some_lookup('some_key')['subkey']"])
|
(b) Get array back, want to filter something out
# Have to write a special 'my_filter' 4.x Ruby function and call it |
Deferred('my_filter', [Deferred('some_lookup', ['some_key']). 'red']) |
# With eval, use a lambda |
Deferred('eval', ["some_lookup('some_key').filter |$x| { $x != 'red' }"])
|
(c) Want two different values as arguments to a call where values come from a first call
# Showing eval first since the Deferred variant is really bad... |
Deferred('eval', ['$tmp = secret_lookup("some_key"); other_func($tmp[0], $tmp[3])'] |
# With deferred - since there is no way to "tee", the glue must either be written as a specific 4.x Ruby function, or you need to lookup twice |
Deferred('other_func', [Deferred('get', [Deferred('some_lookup', ['some_key']), '0']), Deferred('get', [Deferred('some_lookup', ['some_key']), '3'])])
|
There are many variations on those three use cases but I think those three serve as illustration of how eval makes it a lot easier to perform a deferred computation, and how it removes the need to write use case specific 4x Ruby functions. Without eval() you can achieve the same by using EPP/ERB and letting the result be JSON or YAML text that is then parsed. That requires a different set of hoops to jump through, but would be better than having to write use case specific functions. |