Reputation: 3826
I've always been searching for something like Python's while / else struct in Ruby to improve my code.
That means that the loop is executed and if the condition in the loop hasn't been true any time, then it returns the value in the else statement.
In ruby, I can do like this :
if @items.empty?
"Empty"
else
@items.each do |item|
item
end
end
So is there a way to improve this ?
Thank you in advance.
Upvotes: 10
Views: 3644
Reputation: 12578
Since we are in Ruby, let's have fun. Ruby has powerful case
construct, which could be used such as this:
case items
when -:empty? then "Empty"
else items.each { |member|
# do something with each collection member
}
end
But to make the above code work, we have to modify the native class Symbol
first. Modification of native classes is Ruby specialty. This needs to be done only once, typically in a library (gem), and it helps you ever after. In this case, the modification will be:
class Symbol
def -@
Object.new
.define_singleton_method :=== do |o| o.send self end
end
end
This code overloads the unary minus (-
) operator of Symbol
class in such way, that saying -:sym
returns a new empty object monkey patched with :===
method, that is used behind the scenes by the case statement.
Upvotes: 1
Reputation: 15294
A more or less functional way:
empty_action = { true => proc{ "Empty"},
false => proc{ |arr| arr.each { |item| item }} }
empty_action[@items.empty?][@items]
Upvotes: 0
Reputation: 708
Remember that the iterator block returns what you put into it, which can be tested for further use.
if arr.each do |item|
item.some_action(some_arg)
end.empty?
else_condition_here
end
Upvotes: 29
Reputation: 66837
Hm, you could write it as a ternary:
@items.empty? ? 'Empty' : @items.each { |item| item }
You may want to do something more useful in your block though, since each
is executed for its side effects and returns the original receiver.
Update as per your comment: I guess the closest you could get is something like
unless @items.empty?
@items.each { |item| p item }
else
'Empty'
end
Upvotes: 3