I have a lazy evaluation, where I want the first truthy result resulting from a map operation, and once again I found myself writing .find { |e| e }
on the end of my expression.
Here's a simple example; the array and map block are, of course, different in my real life:
[nil, 2, 3, 4].lazy.map{ |e| e }.find { |e| e }
I'm always a little surprised/disappointed when I have to add the block { |e| e }
to a select
or find
, especially if it's a lazy evaluation, because both - redundantly - seem to be identity functions by default:
> [nil, 2, 3, 4].find { |e| e }
=> 2
> [nil, 2, 3, 4].find
=> #<Enumerator: [nil, 2, 3, 4]:find>
> [nil, 2, 3, 4].find.map { |e| e }
=> [nil, 2, 3, 4]
Does this Enumerator practically differ at all from the one obtained from .each
?
> [nil, 2, 3, 4].each.map { |e| e }
=> [nil, 2, 3, 4]
Similarly with select
, except that's even more unhelpful with lazy:
> [nil, 2, 3, 4].select
=> #<Enumerator: [nil, 2, 3, 4]:select>
> [nil, 2, 3, 4].select { |e| e }
=> [2, 3, 4]
> [nil, 2, 3, 4].select.lazy.force # doing it wrong looks functional!
=> [nil, 2, 3, 4]
> [nil, 2, 3, 4].lazy.select { |e| e }.force
=> [2, 3, 4]
> [nil, 2, 3, 4].lazy.select.force # same without .force
ArgumentError: tried to call lazy select without a block
Are these apparent identities (and ArgumentError
!) useful, or just an opportunity for a better default in a future version of Ruby?