Conditional string building in Ruby I can see a possible performance optimization with declaring 2 arrays and iterating the $fake_widgets only once, but how else can I  make the following conditional string building more elegant in Ruby?

pending_coloring = $fake_widgets.select do |widget|
  widget[:status] == 'awaiting_coloring' &amp;&amp; widget[:owner_color] == @owner.id
end

pending_processing = $fake_widgets.select do |widget|
  widget[:status] == 'awaiting_processing' &amp;&amp; widget[:owner_color] == @owner.id
end

notification_text = "You have "

if pending_coloring.size == 1
  notification_text += "#{pending_coloring.size} widget to color"
elsif pending_coloring.size &gt; 1
  notification_text += "#{pending_coloring.size} widgets to color"
end

if pending_coloring.size &gt; 0 &amp;&amp; pending_processing.size &gt; 0
  notification_text += " and "
end

if pending_processing.size == 1
  notification_text += "#{pending_processing.size} widget to process"
elsif pending_processing.size &gt; 1
  notification_text += "#{pending_processing.size} widgets to process"
end

notification_text += ". Go to widget dashboard"
First of all, you have weird behaviour if pending_coloring and pending_processing are both empty arrays.  The output would then be




You have . Go to widget dashboard





I assume that in such a case, it should just say "Go to widget dashboard".



I think that pluralization ought to be treated as an i18n issue.  Even if your application happens to be English-only for now, it's actually easier to generalize the solution, since pluralization is considered a solved problem in internationalization.  In particular, you can use the i18n gem (which is included in Rails, and is a simple installation with no dependencies even if you aren't using Rails).

require 'i18n'

pending_coloring = …
pending_processing = …

I18n.backend.store_translations :en, 'widget' =&gt; {
    :zero =&gt; nil,
    :one =&gt; '1 widget to %{verb}',
    :other =&gt; '%{count} widgets to %{verb}'
}
coloring_text = I18n.t 'widget', :count =&gt; pending_coloring.size, :verb =&gt; 'color'
processing_text = I18n.t 'widget', :count =&gt; pending_processing.size, :verb =&gt; 'process'

notification_text = if (!coloring_text &amp;&amp; !processing_text) then
  ''
else
  "You have #{[coloring_text, processing_text].compact.join(' and ')}.  "
end + "Go to widget dashboard"