the enumerable module or how i fell in love with ruby
DESCRIPTION
Presented at Cascadia Ruby Conf 2011 July 29, 2011 in Seattle, WA by Haris Amin. The presentation can be viewed here http://confreaks.net/videos/607-cascadiaruby2011-the-enumerable-module-or-how-i-fell-in-love-with-rubyTRANSCRIPT
![Page 1: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/1.jpg)
THE ENUMERABLE MODULEor How I Fell In Love with Ruby!
Haris Amin
Cascadia Ruby Conf 2011
07/29/2011
Monday, August 1, 2011
![Page 2: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/2.jpg)
WHO IS THIS GUY?
• Haris Amin
• Software/Web Developer
• Live in New York City
Monday, August 1, 2011
![Page 3: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/3.jpg)
THESE GUYS MAKE SURE I’M NOT LIVING IN THE STREETS
Monday, August 1, 2011
![Page 4: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/4.jpg)
WHAT WE DO @?
Shoulder Pressing Colleagues
Healthy Programmer Vertebrates
Monday, August 1, 2011
![Page 5: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/5.jpg)
LOOK MA I HAS DEGREE!
• Studies Physics/Math in Undergrad
• E = mc^2 , doesn’t pay for food
• Programming, for me in college was just a means to compute something
Monday, August 1, 2011
![Page 6: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/6.jpg)
LAST TALK I GAVE AT A CONFERENCE?
• Simulation of Viscoelastic Fluids
•What did I do?
• Employed a weighted-norm least-squares finite element method to approximate the solution to Oldroyd-B equations
• So...yeah... for me programming was just a way to compute stuff :)
Monday, August 1, 2011
![Page 7: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/7.jpg)
THOUGHT TO MYSELF...
Arrays & Hashes
ARE FUN!!!!
Monday, August 1, 2011
![Page 8: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/8.jpg)
WHAT IS THE ENUMERABLE MODULE?
• A module, you can MIX IT IN!
• A bunch of methods that work with collections
• Empowers the most notably the Array and Hash classes (among others i.e. Set, Range, File, etc.)
Monday, August 1, 2011
![Page 9: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/9.jpg)
HOW TO ‘MIX-IN’ THE ENUMERABLE?
• A class ‘including’ or ‘mixing-in’ Enumerable must define the ‘#each’ method
• Yielded items from the #each method empower the collection awareness for the class
Monday, August 1, 2011
![Page 10: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/10.jpg)
• The #collect method executes the provided block to all of the values yielded by #each
class PlanetExpress include Enumerable
def each yield “Bender” yield “Frye” yield “Leela” yield “Zoidberg” endend
PlanetExpress.new.collect do |member| “#{member} works at Planet Express”end
Monday, August 1, 2011
![Page 11: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/11.jpg)
BUT WHY IS ENUMERABLE SO...
SEXY!?
...
...
...
Monday, August 1, 2011
![Page 12: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/12.jpg)
LOOK AT ALL THESE METHODS!
•all?, any?, collect, detect, each_cons, each_slice, each_with_index, entries, enum_cons, enum_slice, enum_with_index, find, find_all, grep, include?, inject, map, max, member?, min, partition, reject, select, sort, sort_by, to_a, to_set, zip
Monday, August 1, 2011
![Page 13: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/13.jpg)
PROGRAMMER HAPPINESS
“Programmers often feel joy when they can concentrate on the creative side of programming, so Ruby is designed to
make programmers happy.”- Yukihiro Matsumoto (Matz)
Monday, August 1, 2011
![Page 14: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/14.jpg)
WATCH OUT FOR DR. ZOIDBERG’S TIPS
Monday, August 1, 2011
![Page 15: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/15.jpg)
LET’S TAKE A LOOK AT SOME ENUMERABLE METHODS...
Monday, August 1, 2011
![Page 16: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/16.jpg)
each
• The #each method yields items to a supplied block of code one at a time
• Classes implement #each differently
names = %w{ Frye Leela Zoidberg }
names.each do |name| “#{name} works at Planet Express”end
Monday, August 1, 2011
![Page 17: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/17.jpg)
find
• Elegantly simple, find one item that matches the condition supplied by the block
• Consider how a library like ActiveRecord would reimplemnt find from Enumerable?
names = %w{ Frye Leela Zoidberg }
names.find { |name| name.length > 4}
Monday, August 1, 2011
![Page 18: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/18.jpg)
group_by
• It takes a block, and returns a hash, with the returned value from the block set as the key
• Consider how one could use this as word count for a document/text
names = %w{ Frye Bender Leela Zoidberg }
names.group_by { |name| name.length}# => {4=>["Frye"], 6=>["Bender"], 5=>["Leela"], 8=>["Zoidberg"]}
Monday, August 1, 2011
![Page 19: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/19.jpg)
grep
• Searches for members of the collection according to a pattern.... pattern matching
• It uses the === operator for pattern matching
names = %w{ Frye Bender Leela Zoidberg }
names.grep(/oidber/)# => ["Zoidberg"]
Monday, August 1, 2011
![Page 20: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/20.jpg)
GREP-ALICOUS!
• Using the === allows us to do some fancy matching
•We can grep for types or objects
• Equivalent to stuff.select { |element| String === element}
Dr. Zoidberg’s Tip (The doctor is in!)
stuff = [ “Zoidberg”, Pizza.new, :homeless, “Dr."]stuff.grep(String)# => [ “Zoidberg”, “Dr.”]
Monday, August 1, 2011
![Page 21: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/21.jpg)
map / collection
• Think of it as a transformation method, that applies the block as a transformation
• Always returns a new Array with the transformation applied
•Different then #each, return value matters with #map
names = %w{ Frye Bender Leela Zoidberg }
names.map { |name| name.downcase }# => [“frye”, “bender”, “leela”, “zoidberg” ]
Monday, August 1, 2011
![Page 22: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/22.jpg)
THE DELICIOUS ENUMERATOR... enum ... enum ... enum
Monday, August 1, 2011
![Page 23: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/23.jpg)
ENUMERATOR
•We can create an Enumerator without mixing-in the Enumerable module and still have the power of Enumerable methods
• 3 ways to create Enumerator without mixing-in Enumerable
1. Create Enumerator explicitly with a code block
2. Attach an Enumerator to another object
3. Create Enumerator implicitly with blockless iterators
Monday, August 1, 2011
![Page 24: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/24.jpg)
Create Enumerator explicitly with a code block
• y is the yielder, an instance of Enumerator::Yielder
• You don’t yield from the block, you only append to the yielder
e = Enumerator.new do |y| y << “Frye” y << “Bender” y << “Leela” y << “Zoidberg”end
Monday, August 1, 2011
![Page 25: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/25.jpg)
Attach an Enumerator to another object
• knows/learns how to implement #each from another object
• we’re binding the Enumerator to the #select method of the names array
names = %w { Frye Bender Leela Zoidberg }e = names.enum_for(:select)
Monday, August 1, 2011
![Page 26: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/26.jpg)
Create Enumerator implicitly with blockless iterators
•most iterators when called without a block return an Enumerator
• our blockless iterator returned the same Enumerator as the enum_for approach
names = %w { Frye Leela Bender }
names.enum_for(:select)# => #<Enumerator: ["Frye", "Leela", "Bender"]:map>
names.map# => #<Enumerator: ["Frye", "Leela", "Bender"]:map>
Monday, August 1, 2011
![Page 27: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/27.jpg)
BUT WHY DO WE CARE?
...USES?
Monday, August 1, 2011
![Page 28: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/28.jpg)
Add Enumerability to an existing object
•Now we can use Enumerable methods on our ship object
module PlanetExpress class Ship PARTS= %w{ sprockets black-matter } def survey_parts PARTS.each {|part| yield part } end end end ship = PlanetExpress::Ship.new enum = ship.enum_for(:survey_parts)
Monday, August 1, 2011
![Page 29: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/29.jpg)
Fine Grained Iteration
• An Enumerator is an object, it can maintain state
• Think film reels, state machines, etc...
scenes = %w{ credits opening climax end } e = scenes puts e.nextputs e.nexte.rewind puts e.next
Monday, August 1, 2011
![Page 30: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/30.jpg)
CHAINING ENUMERATORS...
...HMMM
Monday, August 1, 2011
![Page 31: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/31.jpg)
CHAINING ENUMERATORS
•Normally chaining enumerators isn’t very useful
• names.map.select might as well be names.select
•Most enumerators are just passing the array of values down the chain
Monday, August 1, 2011
![Page 32: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/32.jpg)
LAZY SLICE
• Instead of creating a 2-element slices for the whole array in memory, the enumerator can create slices in a “lazy” manner and only create them as they are needed
Dr. Zoidberg’s Tip (can i have a slice)
names = %w { Frye Bender Leela Zoidberg }names.each_slice(2).map do |first, second| “#{first} gets a slice & #{second} gets a slice”end
Monday, August 1, 2011
![Page 33: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/33.jpg)
MAP WITH INDEX...WTF?
• There is no #map_with_index defined in Enumerable
• Ah but we can chain... chain... chain!
Dr. Zoidberg’s Tip (what map? i don’t even know where we are!)
names = %w { Leela Bender Frye Zoidberg }names.map.with_index do |name, i| “#{name} has a rank #{i}”end
Monday, August 1, 2011
![Page 34: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/34.jpg)
THE SET CLASS
Monday, August 1, 2011
![Page 35: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/35.jpg)
WHAT IS SET?
• The Set class is a Standard Lib class in Ruby
• You use it by requiring it explicitly ( require ‘set’ )
• It stores a collection of unordered, unique values
• It mixes-in the Enumerable module
Monday, August 1, 2011
![Page 36: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/36.jpg)
SET IS ENUMERABLEclass Set include Enumerable #... def each block_given? or return enum_for(__method__) @hash.each_key { |o| yield(o) } self endend
• Calls a block for each member of the set passing the member as a parameter
• Returns an enumerator if no block is given
Monday, August 1, 2011
![Page 37: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/37.jpg)
SET IS ENUMERABLE
• Actually uses Hash for implementing unique values
class Set include Enumerable #... def initialize @hash ||= Hash.new enum.nil? and return if block do_with_enum(enum) { |o| add(block[o]) } else merge(enum) end endend
Monday, August 1, 2011
![Page 38: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/38.jpg)
SET IS ENUMERABLE
•Defines its own implementation of Enumerable methods
class Set include Enumerable #... def include? @hash.include?(o) end alias member? include?end
Monday, August 1, 2011
![Page 39: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/39.jpg)
ARE YOU IN LOVE YET?
Monday, August 1, 2011
![Page 40: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/40.jpg)
THEN READ THIS
• This talk was inspired by the AWESOME discussion of Enumerable by David A. Black• READ IT! SPREAD THE WORD!!!!
Monday, August 1, 2011
![Page 41: The Enumerable Module or How I Fell in Love with Ruby](https://reader030.vdocuments.mx/reader030/viewer/2022013118/557cbe11d8b42a59078b48ba/html5/thumbnails/41.jpg)
THANK YOU!
hamin
harisamin
harisamin.tumblr.com
Monday, August 1, 2011