Categories
Uncategorized

FutureRuby: July 9th – 12th, 2009

First Came RubyFringe

RubyFringe logo

I can’t talk about FutureRuby without first talking about RubyFringe.

Last July, the fine folks at Toronto’s Little Coding Shop That Could – Unspace – created one of the best and most memorable conferences I’ve ever attended: RubyFringe. RubyFringe made its mark by taking the standard geek conference formula and turning it on its head. Among the things that distinguished it were:

  • RubyFringe was intentionally a small conference, with its attendance capped at 150 attendees.
  • No sponsors!
  • It had a single conference track, and all presentations took place in the same room.
  • The presentations were vetted carefully by people who really, really, really loved the Ruby programming language. This meant that we got interesting speakers and no vendor pitches. We felt Damien Katz’ pain when he talked about his situation prior to creating CouchDB, grooved as Nick Sieger talked about the parallels between jazz and programming, and stayed glued to our seats as Giles Bowkett gave us his rousing call to action in his 400-slide extravaganza, even though he’d gone well beyond his allotted time and was cutting into lunch (it was that good).
  • They didn’t allow questions at the end of the presentations. In organizer Pete Forde’s words: “Our experience has been that questions are hard to hear, generally of poor quality, often just statements, and almost always an exercise in demonstrating how brilliant the questioner is while dominating the attention of the whole room.”
  • There was a “companion track” for attendees’ non-geeky significant others, where they were taken on a tour of the city while their partners were at the conference.
  • They served some of the best food I’ve ever had at a developer conference. The lunches were at the Downtown Metropolitan Hotel, and the big dinner at the Drake Hotel was beyond anything I’ve ever had at a developer conference.
  • The conference also included parties at some of the best spots in the city, some of which you wouldn’t find on vanilla tourist guides. Better yet, those parties were open bar!
  • Not only was there an opening party at a brewery, complete with stand-up comic, rock band and DJ, but there was a great closing party on Unspace’s roof.
  • The organizers paid attention to little details that set the conference apart, from giving everyone transit passes to heralding speakers as they walked on stage with the song of the choice to the giant polaroid montage featuring every attendee.

The organizers’ decisions in crafting RubyFringe made it a high-quality, memorable and inspiring experience, and its carefully limited scale gave it a sense of community that I could almost describe as familial.

Many people who went declared it the best conference they’d ever attended, and many who passed up the opportunity kicked themselves for missing it. Those pale next to the highest praise for the conference: the fact that after attending RubyFringe, a half-dozen handful of attendees were so inspired that they quit their day jobs to strike out on their own doing Ruby development.

Now Comes FutureRuby

FutureRuby comic

With RubyFringe’s resounding success, it was only natural that people would ask if Unspace would be doing it again next year. They gave it some serious thought – the last thing that they wanted to create was a weak sequel. They didn’t want to simply rehash RubyFringe, but reinvent it, just as they had reinvented the developer conference with RubyFringe.

So they reinvented RubyFringe as FutureRuby.

FutureRuby will take place from July 9th through 12th, and will build on what RubyFringe accomplished. The organizers bill it as “an opportunity to prepare for the future by learning from the mistakes of the past”, and promise us that it won’t just be RubyFringe warmed over – we shouldn’t expect to find the same things in the same places!

What else will it have?

  • Parties and nightly entertainment, three nights in a row
  • FAILCamp (which I co-hosted last year, and which I am invited to host again) is back with a vengeance, and an adorable sailor suit
  • “More better than” swag that you’ll be proud to wear in public
  • The return of the companion track for partners and secret lovers during the conference
  • An amazing two nights of lunches and dinners that you’ll photograph and tweet about
  • Loving attention to all of the details, like excellent wifi, transit passes, and no paid presentations

All the details are in this post at Unspace’s blog, Rethink. You can bet that I’ll be at FutureRuby.

Categories
Uncategorized

Ruby on Rails and Merb Merge!

The Merb/Rails rivalry could’ve gone as depicted on the cover of the science fiction “classic” shown below…

the_human_bat_v_the_robot_gangster

 

(I think Merb would be the Human Bat and Rails would be the Robot Gangster.)

…but instead, the two projects have merged! The result will be the upcoming Rails 3.

The merger is commemorated on a “plaque” page on the Rails site titled The Day Merb Joined Rails, which I’ve excerpted below:

Merb was started two years ago by Ezra Zygmuntowicz as a tiny framework to serve ERb templates from Mongrel. This quickly grew into much more and carved out a niche as an alternative Rails stack. Merbists focused on among other things a small speedy core, being ORM/JavaScript agnostic, and having a rigorous API for extensions.

Along with the expansion in ambition came the fact that Merb and Rails started sharing more and more of the same ideas and even implementation. This lead to a fair amount of unnecessary duplication on both sides of the fence and lead to some paradox of choice. When do I choose one over the other and when?

Rails 3

On December 23rd, we decided to end the duplication and the paradox of choice. That was the day we declared our intentions of bringing the best ideas of Merb into Rails 3. That was the day we announced our commitment to work together.

It’s nice to see this sort of thing happening. It’s more common to see projects forking over the tiniest disagreements, a la “The People’s Front of Judea” in Monty Python’s Life of Brian:

It’s a win for both projects, as well as the users. Rails gets some much-needed optimization, the ability to shed excess weight for speed, framework agnosticism and an API that won’t break with upgrades, and Merb gets a much bigger development community and mindshare momentum that Rails enjoys. Better still, the merger now has both teams’ big brains working on the same project, and isn’t that what the spirit of the DRY principle is all about?

Congratulations to both the Merb and Rails teams! And hey, congrats to all you Ruby/Rails/Merb developers out there too! 2009 just got a little more interesting for all of us.

Links

Categories
Uncategorized

My PDC Interviews: Don Box, Miguel de Icaza, John Lam, Phil Haack and .NET Micro Framework

PDC2008 graphic

A number of people have asked me how many sessions I attended at last week’s Microsoft Professional Developers Conference; my answer was “I only attended the keynotes”. Since every session was recorded on video (with a split screen showing both presenter and presentation) and made available online, I decided to focus on what you can’t replicate outside the conference: getting to know people in the Windows developer community.

It’s standard procedure at Microsoft to assign “buddies” to new hires to help them get acclimated. I have the very good fortune of having John Bristowe as one of my buddies; not only is he a warm and friendly guy, but I also already know him (his sister Ashley and I went to Crazy Go Nuts University together). John’s big on podcasting and was very generous in sharing the interviewer’s chair; he let me do a lot of interviews as a way to both get podcasting practice and introduce myself to people in the Windows world. Thanks, John!

You’re going to need Silverlight to view these videos. If you’re rolling your eyes at the prospect of having to download yet another plugin, keep in mind that Silverlight is a pretty cool tool for writing rich internet apps, I’ll be covering it rather extensively soon, and it’s catching on. Besides, you can’t see the videos without it!

Don Box on My Joining the Dark Side, Demos, Oslo and M, Zombies and How to Pronounce “Azure”

Still from Joey deVilla's interview with Don Box
Click the picture to see the video of the interview.

After introducing myself to Distinguished Engineer (yup, that’s really his title) Don Box as “Microsoft’s Newest Employee”, I told him about my coming to Microsoft from the F/OSS world and asked him to please tell me that I hadn’t made a tragic mistake and ruined my life by coming over to the Dark Side. We also talked about his preparation process for his keynote demo, the Oslo platform and the M programming platform, the proper way to pronounce “Azure” and whether or not Microsoft is ready for the zombie apocalypse.

Useful Don Box/Oslo Links

Miguel de Icaza on Mono

Still from Joey deVilla's interview with Miguel de Icaza
Click the picture to see the video of the interview.

I had a great chat with Mono Project lead Miguel de Icaza about Mono, their answer to Silverlight, the number of people in the Mono Project and how you, as a Windows developer, can take Mono out for a spin. We also talked about how to pronounce “Azure”, and Miguel speculated that the name was a clever choice because the disagreement over its pronunciation is a great way to get people talking about it.

Useful Miguel de Icaza/Mono Links

John Lam on IronRuby

Still from Joey deVilla's interview with John Lam
Click the picture to see the video of the interview.

It’s always good to catch up with Toronto-area guy turned Redmond guy and IronRuby creator John Lam. We had a quick chat about IronRuby and the current state of the project. In the interview, he reminds us that IronRuby is an open source project, talks about the Ruby standard implementation tests it’s currently passing and what to expect from IronRuby in the near future.

Useful John Lam/IronRuby Links

Phil Haack on ASP.NET MVC

Still from Joey deVilla's interview with Phil Haack
Click the picture to see the video of the interview.

Phil Haack not only has the coolest surname for a techie, he’s also got an MVC framework for ASP.NET, just like the ones the Rails, Django and Cake people get to play with. In this interview, we talk about MVC web frameworks for the uninitiated, as well as get his take on how to pronounce “Azure”.

Useful Phil Haack/ASP.NET MVC Links

.NET Micro Framework

Still from Joey deVilla's ".NET Micro Framework" interview
Click the picture to see the video of the interview.

Believe it or not, there’s a .NET framework for embedded devices, the .NET Micro Framework. In this interview, I learn about .NET programming for small devices, the “Dare to Dream Different” contest (where you can win great prizes for coming up with new applications for the .NET Micro Framework) and about what donuts have to do with microcontrollers. Mmm…donuts!

Useful .NET Micro Framework Links

Categories
Uncategorized

Notes from Ruby on Rails Project Night

It’s Back!

Bruce Lee, brandishing "Rails" nunchucksLast Friday marked the return of Ruby on Rails Project Night, a Toronto-based event where developers who worked on Ruby and Rails projects could do in-depth presentations on their current projects or ideas. It was on hiatus for the past couple of months (you can see this entry for the definition of “on hiatus”), but thanks to the efforts of Corina Newby, who helped put together the event at its old venue, it’s back, and judging from the attendance, it was missed. Thanks, Corina, for all your work!

James Robertson

The first speaker was also the special guest (and the reason the event was held on a Friday, as opposed to the typical Monday or Tuesday): James Robertson, whom you may know from his blog Smalltalk Tidbits, Industry Rants. He was on a “Canadian tour”, during which he was talking about the Smalltalk-based web app framework Seaside as well as Webvelocity, which puts the Smalltalk development experience within the browser.

Here’s the abstract for his presentation (from this entry from Corina’s blog):

WebVelocity is a new Smalltalk Development Environment that is oriented around Seaside for Web Development and Glorp for Object/Relatonal Mapping. Come and see how WebVelocity re-targets the Smalltalk development experience into the Web Browser and simplifies the challenge of learning a new environment for newcomers. We’ll even build an entire application using Active Record and Scaffolding during the presentation, with minimal programming. If you’re a fan of Ruby on Rails, you need to come out and see this presentation!

Here are my notes from his presentation:

- Seaside is open source, but Smalltalk ain't
- Seaside is maintained in Squeak, which you could call "the open source Smalltalk"
    
- Ruby on Rails is opinionated
- "Seaside is also opinated; it just has different opinions"
- When building Seaside, Avi Bryant asked "What if I took all the assumptions about web apps...
  and ignored them?"
- Some of what I show you is what happens when you blow those assumptions

- The canonical Seaside example -- the number increment/decrement button
  (now we know where that disastrous DemoCamp Seaside presentation came from!)
- Seaside uses continuations to remember state
- They enable "proper" support for the backbutton
- Session state info is keyed via a cryptographically secure key in the URL
    
- With Rails, you're dealing with two different worlds: templates and code
- Seaside is just one world: You don't write any HTML at all, you write all Smalltalk
- It's all in one place
- Support for debugger -- you can debug web apps as if they were desktop apps, with breakpoints and resumes
- In Seaside, the "html" argument is a "brush" that knows how to "paint" HTML
- You can debug in the middle of a page hit
    
- In beta: Seaside totally within the browser
- Editing code within a webpage, including tooltips and color hinting
- Every time a method is entered and it is syntactically correct, it is auto-saved -- no need to manual save!
- [Shows a Smalltalk debugger with an Ajax front end]
- "In some ways, it's even more productive than the real Smalltalk environment is"
- [Smalltalk console within the browser]
- [Auto-indenting within the browser]
- [Auto-generates a scaffolding-like page]
- The "call" method lets you write web app code very much like writing GUI stuff

Paul Doerwald

The second speaker was Paul Doerwald, who changed his topic from the more Ruby/Rails-specific “insights gained from working with ActiveRecord validation” to a more general (but still interesting) topic: Agile Documentation. He figured that it might be a better fit with James’ presentation, and it was — it was also quite interesting.

Here’s the abstract for his presentation:

“Programmers generally hate writing documentation. That’s because most documentation is kept separate from the code and becomes hard to keep up-to-date. Besides violating the DRY principle… it can lead to misleading documentation, which is generally worse than none at all.” [Subramaniam/Hunt ’06]. Why do developers hate writing documentation, and why do stakeholders and managers keep requiring it? Is there agile documentation beyond inline API documentation (JavaDoc, RDoc, etc.) and comments in the code? What parts of a project deserve separate-from-code documentation? How do we identify them, capture them, and keep them relevant?

Tonight’s Toronto Ruby on Rails Project Night presentation discusses the problem of documentation, explores some key aspects to consider when writing effective documentation, and dreams of a future of testable, executable documentation, where non-code knowledge could be integrated into your code.“

And here are my notes from his talk:

- My original presentation was going to be about insights gained from ActiveRecord validation
- But I've decided to change it -- it's now on Agile Documentation
- It's my M.Sc. Thesis!
- "You'll find this talk a bit heavy on problem and not so heavy on solution"
- Think of this as an introduction -- I want to frame things and ask:
  what is Agile Documentation?

- By "documentation", I mean by the kind that's by programmers for programmers
    
- It's not a particularly sexy area
- Frameworks are sexy:
    - Rails is sexy
    - Django is sexy
    - CakePHP is sexy...(for PHP)
- Languages are sexy
    - Ruby is sexy
    - Objective-C is..."strangely alluring"
- Even databases are sexy! Consider CouchDB and AWS
- What's not sexy?
    - Documentation
    - Backup -- at least not until Apple's Time Machine
    - Both are viewed as a waste of time
    
- We're developers. We may grudgingly accept the presence of non-developer things,
  but we don't want to do them
- Documentation is hard to write
- It seems so much easier to program rather than write
- Writing -- the non code-type -- is not our core competency
- We say "Our code is the authoritative documentation!"
- Consider what DHH said in a "Signal vs. Noise" blog entry in February 2006
    - When asked "How do you document your projects?", he replied "We don't."
    - He also said:
        - "Never worked consistently or successfully"
        - "Not necessary for our work"
        - "Most Rails developers can walk in and find out"
        - "We use Ruby"
        - "Method docs only for non-obvious behaviour"
        - "Docs mean BDUF"
        - "Appropriate only for onerous enviroments with complex policies"
        - "Focus on code quality instead"
    
- Like backups, docs are important
- We're not the only people who'll be working on a project, especially if it's a success
- We don't want to feel like we're wasting time when we're working
- Running a documentation tool and taking its output and pasting it into a Word doc is not DRY
- Why are we writing highly-coupled docs?
    
- Is there such a thing as agile documentation? I'm going to say yes
- Look at the Agile Manifesto
    - "We value working software over comprehensive documentation"
    - But it doesn't say that comprehensive documentation isn't valued!
        
- What's the state of the Art
    - For API Documentation, it's JavaDoc
    - In Rails, the outer classes are well documented, but not the inner ones
    - The JDK is extremely well-documented
    - You could say that RSpec is a form of agile documentation
    - It's a stretch, but Domain-Specific Languages could also be agile documentation
    - After all these, I can only think of process
    - When do we do docs? At the beginning of the process? At the end?
            
- What could agile documentation look like? What does it feel like?
- I borrowed principle from Alastair Cockburn's "Agile Software Development:
  The Cooperative Game, 2nd ed."
- The goals set out in the book:
    - Finish the game (i.e. finish development and launch the product)
    - Set up the game for the next team
    - Think of pool: maybe you take the hard shot first to set yourself up later for the easy shot
    - Coburn calls this "residue": the stuff that one team leaves behind for the next team
    - Residue includes:
        - Code
        - Process in place
        - Documentation

- I would argue that DHH/37signals has an oral form of documentation
- It works if the company doesn't grow too quickly
- What are we really asking for when we ask for the documentation: Tacit Knowledge
    - "That which is seen but not noticed"
    - It is information that is understood and implied but not stated
    - If you've ever brought someone else onto a team, you spend a lot of time
      explaining things that are obvious to you
    - You might not explain that stuff if you're doing it on paper
    - You don't want to end up in a situtation where there's too much documentation
        
- What can we borrow from software engineering principles?
    - Orthogonality
        - A good thing in software development
        - Intersect at a clear and obvious point and do not influence each other at any other point
    - Cohesion
        - All attributes and methods are related to the essence of the class
        - Don't have people look in 5 different places to get the answer to a single question
    - Coupling
        - The extent to which one thing is dependent on each other
    
- To the future
    - 5 years ago, unit testing was unheard of in the web development world
    - Rails and similar projects have helped popularize unit testing
    - We've moved from the point to where we say "testing is awesome"
    - Testing is now a core value
    - Can we make documentation a core value?
    
- Agile documentation processes
    - Large companies are good at this; open source people not so good
    - Looking to Rails:
        - Documentaton conventions?
        - What if we had 5 steps for writing documentation that did 70% of the work?        
    - Can we integrate documentation with code?
        - In many cases, the docs exist as a Word document
        - A step up is to use a Wiki -- support for multiple authors, versioning, linking
        - Can we put docs right in the codebase?
        - Every Rails app has a doc directory -- can we use that?
        - We test code -- is there a way to make testable documentation?
        - What if we could tag a method and class with a keyword and make that keyword appear in the docs?
          -- We could generate an alert when changes happen

Checking Out the Rich Media Institute

After the presentation, which was held in the Rich Media Institute’s basement-level lecture room, a number of us headed upstairs to check out its main floor. If you’re a techie with a creative bent, this place is like a candy store. The front part is a store full of books, t-shirts, music and other goodies that new media creators and aficionados would love, while the back is a gallery for local interactive artists’ works.

I took some photos of the place and posted them in the gallery below. Click on any of the thumbnails to see a larger version of the picture:

Categories
Uncategorized

The Return of Ruby on Rails Project Night

Rails to Victory

After “a much-needed summer hiatus” (which you can read as “the complete implosion of Toronto’s worst-run software development shop, which used to host the event”) Ruby on Rails Project Night makes its comeback this Friday, September 19th at its new home at the Rich Media Institute in Kensington Market.

Event organizer Corina Newby promises that it won’t normally be on Fridays, which should the minds of your significant others, party-going friends or World of Warcraft clans at ease. The event is being held on a Friday this time to accommodate the schedule of special guest James “Smalltalk Tidbits, Industry Rants” Robertson, who’ll be there to give us a presentation of the Smalltalk-based web application framework Seaside and the Seaside-based Smalltalk development environment WebVelocity.

Also scheduled is local Ruby on Rails developer Paul Doerwald, who’ll be doing a presentation on insights he gained from working with ActiveRecord validation.

As always, one of the greatest benefits of these gatherings is actually meeting local developers who work with or are interested in working with Ruby and Rails. It’s good for you, your software development career and the future of Accordion City as a hub for high-tech when gatherings like this take place, so be a part of it!

By the way, did I mention that the event is FREE?

Once again, the date is this Friday, September 19th at the Rich Media Institute (156 Augusta Avenue). The presentations will start at 6 p.m. and run until about 7:30. If you’re planning to attend, let Corina know at corecorina@hotmail.com.

Categories
Uncategorized

Enumerating Enumerable: A Cute Trick for Explaining inject / reduce / fold

Enumerating Enumerable

The next method I’m going to cover in Enumerating Enumerable — the series of articles in which I try to do a better job of documenting Ruby’s Enumerable module than Ruby-Doc.org does — is inject, a.k.a. reduce. Not only is it one of the trickiest methods to explain, it’s also one of the cornerstones of functional programming. I thought that I’d take a little time to explain what the function does.

inject

The term inject comes from Smalltalk and isn’t terribly descriptive. I remember reading the documentation for it and being all confused until I saw some examples. I then realized that I’d seen this function before, but under two different names.

reduce

The Second-Best Accordion Picture Ever
Burning Man 1999: gratuitous nudity and even more gratuitous accordion!

The second name by which I encountered this function is reduce, and it was at Burning Man 1999. I was to start a new job the week after Burning Man, and I had to learn at least some basic Python by then. So along with my camping gear, accordion and a kilo of candy for barter, I also brought my laptop (a 233Mhz Toshiba Sattelite with a whopping 96MB of RAM) and O’Reilly’s Learning Python and noodled during the downtime (early morning and afternoon) on Python 1.6. When I got to covering the reduce function, I was confused until I saw some examples, after which I realized that I’d seen that function before, but under a different name.

(You may have also heard of reduce through Google’s much-vaunted MapReduce programming model.)

fold

The first name by which I encountered this function is fold, or more specifically, “fold left” or “foldl”, and it was at the “Programming Paradigms” course I took at Crazy Go Nuts University. “Programming Paradigms” was a second-year course and had the reputation of being the most difficult course in the computer science curriculum. The intended purpose of this course was to provide students with an introduction to functional programming (these days, they use Haskell and Prolog, back then, it was Miranda). Its actual effect was to make most of the students swear off functional programming for the rest of their lives.

In spite of the trauma from this course, I ended up remembering a lot from it that I was able to apply, first to Python and now to Ruby. One of these things is a cute little trick for cememnting in your mind what fold does.

What Ruby-doc.org Says

Before I cover that cute little trick, let’s take a look at what Ruby-doc.org’s documentation has to say about Enumerable‘s inject method.

One thing you’ll find at Ruby-doc.org is that as of Ruby 1.8.7 and later, inject gained a synonym: the more familiar term reduce.

As for the description of the inject/reduce method, I don’t find it terribly helpful:

Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator.

If you specify a block, then for each element in enum<i> the block is passed an accumulator value (<i>memo) and the element. If you specify a symbol instead, then each element in the collection will be passed to the named method of memo. In either case, the result becomes the new value for memo. At the end of the iteration, the final value of memo is the return value fo the method.

If you do not explicitly specify an initial value for memo, then uses the first element of collection is used as the initial value of memo.

(Yes, those stray <i> tags are part of the text of the description for inject. Hopefully they’ll fix that soon.)

This confusing text becomes a little clearer with some examples. The most typical example of inject/reduce/fold in action is the classic “compute the sum of the numbers in this range or array” problem. There are a number of approaches you can take in Ruby, all of which use inject/reduce:

(1..8).reduce(:+)
=> 36

(1..8).reduce {|sum, number| sum += number}
=> 36

(1..8).reduce(0) {|sum, number| sum += number}
=> 36

The reduce method takes some kind of operation and applies it across the enumerable to yield a single result. In this case, the operation is addition.

Explaining how that operation is applied is a little trickier, but I do just that in the next section.

Demonstrating inject / reduce / fold With a Piece of Paper and Literal Folding

To explain what’s happening in the code above, I’m going to do use a piece of paper. I’ve folded it into 8 even sections and then numbered each section, as shown in the photo below:

Think of the paper as the range (1..8). We’re now going to compute the sum of the numbers in this range, step by step, using a literal fold — that is, by folding the paper. I’m going to start folding from the left side of the paper, and when I do, I’m going to add the numbers that I’m folding into each other.

In the first fold, I’m folding the number 1 onto the number 2. Adding these two numbers yields 3, which I write on the back of the fold:

For the second fold, I fold the first number 3 onto the second number 3. The sum of these two numbers is 6, and I write that on the back of the resulting fold:

I fold again: this time, it’s the number 6 onto the number 4, the sum of which is 10. I write that number down on the resulting fold:

Next, I fold 10 onto 5, yielding the number 15:

I then fold 15 onto 6, which gives me 21:

Next comes 21 folded onto 7, which makes for a sum of 28:

And finally, 28 folded onto 8, which gives us a final total of 36.

And there you have it: a paper-based explanation of inject/reduce/fold, as well as why I often refer to the operation as “folding”.

Categories
Uncategorized

Enumerating Enumerable: Enumerable#group_by

Enumerating Enumerable

Once again, it’s Enumerating Enumerable time! This is the latest in my series of articles where I set out to make better documentation for Ruby’s Enumerable module than Ruby-Doc.org’s. In this installment — the seventeenth in the series — I cover the group_by method.

In case you missed any of the previous articles, they’re listed and linked below:

  1. all?
  2. any?
  3. collect / map
  4. count
  5. cycle
  6. detect / find
  7. drop
  8. drop_while
  9. each_cons
  10. each_slice
  11. each_with_index
  12. entries / to_a
  13. find_all / select
  14. find_index
  15. first
  16. grep

Enumerable#group_by Quick Summary

Graphic representation of the "group_by" method in Ruby's "Enumerable" module.

In the simplest possible terms Break a collection into groups based on some given criteria.
Ruby version 1.9 only
Expects A block containing the criteria by which the items in the collection will be grouped.
Returns A hash where each key represents a group. Each key’s corresponding value is an array containing the members of that group.
RubyDoc.org’s entry Enumerable#group_by

Enumerable#group_by and Arrays

When used on an array, group_by iterates through the array, passing each element to to the block. The result value of the block is the group into which the element will be placed.

Example 1

For the first example, I’ll use some code similar to the example given in Ruby-doc.org’s writeup of group_by:

(0..15).group_by {|number| number % 3}
=> {0=>[0, 3, 6, 9, 12, 15], 1=>[1, 4, 7, 10, 13], 2=>[2, 5, 8, 11, 14]}

In the code above, the numbers 0 through 15 are passed to the block, which receives each number as the parameter number. The group that each number is placed into is determined by the result value of the block, number % 3, whose result can be one of 0, 1 or 2. This means that:

  • The resulting hash will have three groups, represented by the keys 0, 1 and 2
  • The key 0‘s corresponding value is an array containing the numbers in the range (0..15) that are evenly divisible by 3 (i.e. the numbers for which number % 3 is 0.
  • The key 1‘s corresponding value is an array containing the numbers in the range (0..15) that when divided by 3 leave a remainder of 1 (i.e. the numbers for which number % 3 is 1.
  • The key 2‘s corresponding value is an array containing the numbers in the range (0..15) that when divided by 3 leave a remainder of 2 (i.e. the numbers for which number % 3 is 2.

Example 2

In the first example, the keys in the resulting hash are the same type as the values in the array whose contents we’re grouping. In this example, I’ll show that the keys in the resulting hash don’t have to be the same type as the values in the array.

simpsons = %w(Homer Marge Bart Lisa Abraham Herb)
=> ["Homer", "Marge", "Bart", "Lisa", "Abraham", "Herb"]

simpsons.group_by{|simpson| simpson.length}
=> {5=>["Homer", "Marge"], 4=>["Bart", "Lisa", "Herb"], 7=>["Abraham"]}

In the code above, each Simpson name is passed to the block, which receives it as the parameter simpson. The block’s result is the length of simpson, and this result is the group into which the name will go.

In the resulting hash:

  • Note that the keys are integers while the names in the groups are strings.
  • The key 5‘s array contains those names in Simpsons that are 5
    characters in length.
  • The key 4‘s array contains those names in Simpsons that are 4 characters in length.
  • The key 7‘s array contains those names in Simpsons that are 7 characters in length.

Example 3

In the previous two examples, the keys for the resulting array were calculated from the values in the initial array. In this example, I’ll demonstrate that the keys for the groupings can be determined in a completely arbitrary fashion that has nothing to do with the values:

# Put the Simpsons into randomly determined groups
simpsons.group_by{rand(3) + 1}
=> {3=>["Homer", "Bart", "Abraham", "Herb"], 1=>["Marge", "Lisa"]}

# Let's try that again. The results are very likely to be different:
simpsons.group_by{rand(3) + 1}
=> {1=>["Homer", "Bart"], 2=>["Marge", "Lisa", "Herb"], 3=>["Abraham"]}

# One more time!
simpsons.group_by{rand(3) + 1}
=> {2=>["Homer", "Bart", "Lisa"], 3=>["Marge", "Herb"], 1=>["Abraham"]}

Enumerable#group_by and Hashes

When used on a hash, group_by passes each key/value pair in the hash to the block, which you can “catch” as either:

1. A two-element array, with the key as element 0 and its corresponding value as element 1, or
2. Two separate items, with the key as the first item and its corresponding value as the second item.

Example 1

In this example, we’ll group the cast of Family Guy by the item that they’re bringing to a potluck dinner:

potluck = {"Peter" => "lasagna",
           "Lois"  => "potato salad",
           "Chris" => "lasagna",
           "Meg"   => "brownies",
           "Stewie" => "chateaubriand",
           "Brian" => "potato salad",
           "Evil Monkey" => "potato salad"}
=> {"Peter"=>"lasagna", "Lois"=>"potato salad", "Chris"=>"lasagna", "Meg"=>"brownies",
"Stewie"=>"chateaubriand", "Brian"=>"potato salad", "Evil Monkey"=>"potato salad"}

# Here's one way to do it:
potluck.group_by{|person, bringing| bringing}
=> {"lasagna"=>[["Peter", "lasagna"], ["Chris", "lasagna"]], "potato salad"=>[["Lois", "potato salad"],
["Brian", "potato salad"], ["Evil Monkey", "potato salad"]], "brownies"=>[["Meg", "brownies"]],
"chateaubriand"=>[["Stewie", "chateaubriand"]]}

# Here's another way to do it:
potluck.group_by{|person| person[1]}
=> {"lasagna"=>[["Peter", "lasagna"], ["Chris", "lasagna"]], "potato salad"=>[["Lois", "potato salad"],
["Brian", "potato salad"], ["Evil Monkey", "potato salad"]], "brownies"=>[["Meg", "brownies"]],
"chateaubriand"=>[["Stewie", "chateaubriand"]]}

Example 2

In the previous example, the groupings were based on a calculation performed on the objects in the original hash. In this example, the groupings will be random: a random number generator will determine whose car each potluck attendee will ride to the potluck dinner:

potluck.group_by {[:peters_car, :quagmires_car, :clevelands_car][rand(3)]}
=> {:peters_car=>[["Peter", "lasagna"], ["Chris", "lasagna"], ["Evil Monkey", "potato salad"]],
:quagmires_car=>[["Lois", "potato salad"], ["Meg", "brownies"], ["Stewie", "chateaubriand"]],
:clevelands_car=>[["Brian", "potato salad"]]}

# Let's try another random grouping
potluck.group_by {[:peters_car, :quagmires_car, :clevelands_car][rand(3)]}
=> {:peters_car=>[["Peter", "lasagna"], ["Meg", "brownies"]], :quagmires_car=>[["Lois", "potato salad"],
["Stewie", "chateaubriand"], ["Brian", "potato salad"], ["Evil Monkey", "potato salad"]],
:clevelands_car=>[["Chris", "lasagna"]]}

# One more time!
potluck.group_by {[:peters_car, :quagmires_car, :clevelands_car][rand(3)]}
=> {:peters_car=>[["Peter", "lasagna"], ["Chris", "lasagna"], ["Stewie", "chateaubriand"]],
:quagmires_car=>[["Lois", "potato salad"], ["Evil Monkey", "potato salad"]], :clevelands_car=>[["Meg", "brownies"],
["Brian", "potato salad"]]}