Project

General

Profile

Actions

Feature #9867

closed

Introduce each/else block into ruby

Added by Killa (Łukasz Strzebińczyk) almost 10 years ago. Updated over 6 years ago.

Status:
Closed
Target version:
-
[ruby-core:62796]

Description

Hi

Code like this happens quite often:

if array.any?
  array.each do |elem|
    some_work
  end
else
  do_something_else
end

I was thinking if it was possible, to introduce syntax like this:

array.each do |elem|
  some_work
else
  do_something_else
end

where code in else would fire if array is empty. This would simplify a lot of code nicely and would be completely backwards compatible. Is that a good idea?

Updated by nobu (Nobuyoshi Nakada) almost 10 years ago

  • Status changed from Open to Feedback

How would you define else block for other than Array#each?

Updated by matz (Yukihiro Matsumoto) almost 10 years ago

We have to define as a whole. If we have introduced your proposal, what should the semantics of a block be?
Or how we could invoke else part when we define our own each-like method?

Matz.

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 10 years ago

I'm curious. Personally I don't remember any time I used something like this. Would you mind showing some examples where it happens in your application?

Updated by Killa (Łukasz Strzebińczyk) almost 10 years ago

I came up with this idea after some study on http://handlebarsjs.com/. In that case, the 'else' block is invoked when collection is empty.
This would have clear translation for Array or Hash, however I'm having a problem trying to define this in more global matter.
As for the example, this is quite common case when printing out some collection in erb or any other:

<% if @rooms.any?%>
  <% @rooms.each do |room| %>
    <%= render "room", room: room %>
  <% end %>
<% else %>
  There are no rooms created yet. <%= link_to "Create first room!", new_room_path %>
<% end %>

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) almost 10 years ago

Ah, now I see. Indeed it would be useful for templates processing. Since I barely write any ERB those days, that's probably the reason why I never needed something like that... For example, this is how I'd handle those cases usually in my methods:

(do_something_else; return) if array.empty?
array.each {...}

But even this is not that much common in my code. Way more common is the situation where a variable could be even an array or not be present (in which case I'd get nil). In such cases I often write code like:

(hash[:array] || []).each{...}
# or:
Array(hash[:array]).each{...}

But I can definitely see how your proposal would be useful for template languages, like ERB.

It's also interesting to point out that other people seem to be interested on a better approach for handling this case:

http://stackoverflow.com/questions/1027871/rails-an-elegant-way-to-display-a-message-when-there-are-no-elements-in-databas

Here's one suggested idiom for dealing with it that you might consider:

<% if @messages.each do |message| %>
  <%# code or partial to display the message %>
<% end.empty? %>
  You have no messages.
<% end %>

Updated by sawa (Tsuyoshi Sawada) almost 10 years ago

Łukasz Strzebińczyk wrote:

... the 'else' block is invoked when collection is empty.

Your proposal is about any?, but your explanation mentions emptiness, or empty?, and so the usecase and the proposal do not match. Are you confusing any? with negation of empty?? In some cases, the former can be a shorthand for the latter, but they are different.

If your real intention was to condition the first part by the negation of empty? rather than any?, then you don't need to condition for the first part as empty array will have nothing to iterate over. It can be simply written as:

array.each do |elem|
  some_work
end
unless array.any?
  do_something_else
end

Updated by Killa (Łukasz Strzebińczyk) over 9 years ago

Sorry for the delay.
I don't think I am able in specifying it in needed level of detail: (. If that's up to me, the issue can be closed.

Actions #8

Updated by marcandre (Marc-Andre Lafortune) over 6 years ago

  • Status changed from Feedback to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0