Very often in Ruby (and Rails specifically) you have to check if something exists and then perform an action on it, for example:
if @objects.any?
puts "We have these objects:"
@objects.each { |o| puts "hello: #{o}"
end
This is as short as it gets and all is good, but what if you have @objects.some_association.something.hit_database.process
instead of @objects
? I would have to repeat it second time inside the if
expression and what if I don't know the implementation details and the method calls are expensive?
The obvious choice is to create a variable and then test it and then process it, but then you have to come up with a variable name (ugh) and it will also hang around in memory until the end of the scope.
Why not something like this:
@objects.some_association.something.hit_database.process.with :any? do |objects|
puts "We have these objects:"
objects.each { ... }
end
How would you do this?
Note that there's no reason to check that an array has at least one element with any?
if you're only going to send each
, because sending each
to an empty array is a no-op.
To answer your question, perhaps you are looking for https://github.com/raganwald/andand?
Indeed, using a variable pollutes the namespace, but still, I think if (var = value).predicate
is is a pretty common idiom and usually is perfectly ok:
if (objects = @objects.some_association.hit_database).present?
puts "We have these objects: #{objects}"
end
Option 2: if you like to create your own abstractions in a declarative fashion, that's also possible using a block:
@objects.some_association.hit_database.as(:if => :present?) do |objects|
puts "We have these objects: #{objects}"
end
Writing Object#as(options = {})
is pretty straigthforward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With