From: Leslie Viljoen Date: 2008-02-23T00:19:35+09:00 Subject: Re: ||= [] idiom On Fri, Feb 22, 2008 at 2:33 PM, Thufir wrote: > On Wed, 20 Feb 2008 07:21:15 +0900, MenTaLguY wrote: > > > I sometimes do this sort of thing: > > > > ( @categories[resource.tag] ||= [] ) << resource > > > > Although this might possibly be more readable: > > > > category = ( @categories[resource.tag] ||= [] ) category << resource > > > > Often it can make sense to factor the ||= portion into a separate > > method: > > > > def category_for(tag) > > @categories[tag] ||= [] > > end > > > > # ... > > > > category_for(resource.tag) << resource > > > > -mental > > > > What's the real-world application of this? It's for making hashes of arrays: class Article attr_accessor :name, :month def initialize(name, month) @name = name @month = month end end articles = [ Article.new("Article1", "Feb"), Article.new("Article2", "Feb"), Article.new("Article3", "Feb"), Article.new("Article4", "Mar"), Article.new("Article5", "Mar"), ] months = {} articles.each do |a| months[a.month] ||= [] months[a.month] << a.name end p months >> {"Feb"=>["Article1", "Article2", "Article3"], "Mar"=>["Article4", "Article5"]} Now that is easy to iterate through and produce a tree: Feb: Article1 Article2 Article3 Mar: Article4 Article5 ... This sets an element for key "a.month" (the article's month) to an empty array if it is currently set to nil: months[a.month] ||= [] This adds "a.name" (the article's name) to the array that already exists or has just been created above: months[a.month] << a.name Les