THE ENUMERABLE MODULE                         or How I Fell In Love with Ruby!                                  Haris Amin...
WHO IS THIS GUY?    • Haris Amin    • Software/Web           Developer    • Live         in New York CityMonday, August 1,...
THESE GUYS MAKE SURE I’M         NOT LIVING IN THE STREETSMonday, August 1, 2011
WHAT WE DO @           ?                               Shoulder Pressing Colleagues          Healthy Programmer           ...
LOOK MA I HAS DEGREE!    • Studies            Physics/Math in Undergrad    •E       = mc^2 , doesn’t pay for food    • Pro...
LAST TALK I GAVE AT A                            CONFERENCE?    • Simulation             of Viscoelastic Fluids    • What ...
THOUGHT TO MYSELF...                         Arrays & Hashes                          ARE FUN!!!!Monday, August 1, 2011
WHAT IS THE ENUMERABLE                   MODULE?    •A        module, you can MIX IT IN!    •A        bunch of methods tha...
HOW TO ‘MIX-IN’ THE                           ENUMERABLE?    •A    class ‘including’ or ‘mixing-in’ Enumerable must define ...
class PlanetExpress                           include Enumerable                           def each                       ...
BUT WHY IS ENUMERABLE             SO...                           ...                           ...                       ...
LOOK AT ALL THESE                            METHODS!  • all?, any?, collect, detect, each_cons, each_slice,      each_wit...
PROGRAMMER                           HAPPINESS“Programmers often feel joy when they can concentrate on the creative side o...
WATCH OUT FOR DR.                          ZOIDBERG’S TIPSMonday, August 1, 2011
LET’S TAKE A LOOK AT SOME        ENUMERABLE METHODS...Monday, August 1, 2011
each             names = %w{ Frye Leela Zoidberg }             names.each do |name|               “#{name} works at Planet...
find             names = %w{ Frye Leela Zoidberg }             names.find { |name| name.length > 4}            • Elegantly...
group_by             names = %w{ Frye Bender Leela Zoidberg }             names.group_by { |name| name.length}            ...
grep             names = %w{ Frye Bender Leela Zoidberg }             names.grep(/oidber/)             # => ["Zoidberg"]  ...
GREP-ALICOUS!             stuff = [ “Zoidberg”, Pizza.new, :homeless, “Dr."]             stuff.grep(String)             # ...
map / collection             names = %w{ Frye Bender Leela Zoidberg }             names.map { |name| name.downcase }      ...
THE DELICIOUS ENUMERATOR                         ... enum ... enum ... enumMonday, August 1, 2011
ENUMERATOR    • We   can create an Enumerator without mixing-in the        Enumerable module and still have the power of E...
Create Enumerator explicitly with a code block                            e =   Enumerator.new do |y|                     ...
Attach an Enumerator to another object                         names = %w { Frye Bender Leela Zoidberg }                  ...
Create Enumerator implicitly with blockless iterators           names = %w { Frye Leela Bender }           names.enum_for(...
BUT WHY DO WE CARE?                         ...USES?Monday, August 1, 2011
Add Enumerability to an existing object                         module PlanetExpress                            class Ship...
Fine Grained Iteration                         scenes = %w{ credits opening climax end }                         e = scene...
CHAINING ENUMERATORS...                         ...HMMMMonday, August 1, 2011
CHAINING ENUMERATORS    • Normally           chaining enumerators isn’t very useful    • names.map.select           might ...
LAZY SLICE             names = %w { Frye Bender Leela Zoidberg }             names.each_slice(2).map do |first, second|   ...
MAP WITH INDEX...WTF?             names = %w { Leela Bender Frye Zoidberg }             names.map.with_index do |name, i| ...
THE SET CLASSMonday, August 1, 2011
WHAT IS SET?    • The          Set class is a Standard Lib class in Ruby    • You          use it by requiring it explicit...
SET IS ENUMERABLE                         class Set                           include Enumerable                          ...
SET IS ENUMERABLE                         class Set                           include Enumerable                          ...
SET IS ENUMERABLE                         class Set                           include Enumerable                          ...
ARE YOU IN LOVE YET?Monday, August 1, 2011
THEN READ THIS      • Thistalk was inspired by the AWESOME discussion of        Enumerable by David A. Black      • READ I...
THANK YOU!                            hamin                            harisamin                            harisamin.tumb...
Upcoming SlideShare
Loading in …5
×

The Enumerable Module or How I Fell in Love with Ruby

10,353 views

Published on

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-ruby

Published in: Technology, Education
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
10,353
On SlideShare
0
From Embeds
0
Number of Embeds
1,159
Actions
Shares
0
Downloads
46
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

The Enumerable Module or How I Fell in Love with Ruby

  1. 1. THE ENUMERABLE MODULE or How I Fell In Love with Ruby! Haris Amin Cascadia Ruby Conf 2011 07/29/2011Monday, August 1, 2011
  2. 2. WHO IS THIS GUY? • Haris Amin • Software/Web Developer • Live in New York CityMonday, August 1, 2011
  3. 3. THESE GUYS MAKE SURE I’M NOT LIVING IN THE STREETSMonday, August 1, 2011
  4. 4. WHAT WE DO @ ? Shoulder Pressing Colleagues Healthy Programmer VertebratesMonday, August 1, 2011
  5. 5. 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 somethingMonday, August 1, 2011
  6. 6. 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
  7. 7. THOUGHT TO MYSELF... Arrays & Hashes ARE FUN!!!!Monday, August 1, 2011
  8. 8. 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
  9. 9. 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 classMonday, August 1, 2011
  10. 10. class PlanetExpress include Enumerable def each yield “Bender” yield “Frye” yield “Leela” yield “Zoidberg” end end PlanetExpress.new.collect do |member| “#{member} works at Planet Express” end • The #collect method executes the provided block to all of the values yielded by #eachMonday, August 1, 2011
  11. 11. BUT WHY IS ENUMERABLE SO... ... ... ... SEXY!?Monday, August 1, 2011
  12. 12. 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, zipMonday, August 1, 2011
  13. 13. 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
  14. 14. WATCH OUT FOR DR. ZOIDBERG’S TIPSMonday, August 1, 2011
  15. 15. LET’S TAKE A LOOK AT SOME ENUMERABLE METHODS...Monday, August 1, 2011
  16. 16. each names = %w{ Frye Leela Zoidberg } names.each do |name| “#{name} works at Planet Express” end • The #each method yields items to a supplied block of code one at a time • Classes implement #each differentlyMonday, August 1, 2011
  17. 17. find names = %w{ Frye Leela Zoidberg } names.find { |name| name.length > 4} • Elegantly simple, find one item that matches the condition supplied by the block • Consider how a library like ActiveRecord would reimplemnt find from Enumerable?Monday, August 1, 2011
  18. 18. group_by names = %w{ Frye Bender Leela Zoidberg } names.group_by { |name| name.length} # => {4=>["Frye"], 6=>["Bender"], 5=>["Leela"], 8=>["Zoidberg"]} • 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/textMonday, August 1, 2011
  19. 19. grep names = %w{ Frye Bender Leela Zoidberg } names.grep(/oidber/) # => ["Zoidberg"] • Searches for members of the collection according to a pattern.... pattern matching • It uses the === operator for pattern matchingMonday, August 1, 2011
  20. 20. GREP-ALICOUS! stuff = [ “Zoidberg”, Pizza.new, :homeless, “Dr."] stuff.grep(String) # => [ “Zoidberg”, “Dr.”] • 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!)Monday, August 1, 2011
  21. 21. map / collection names = %w{ Frye Bender Leela Zoidberg } names.map { |name| name.downcase } # => [“frye”, “bender”, “leela”, “zoidberg” ] • 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 #mapMonday, August 1, 2011
  22. 22. THE DELICIOUS ENUMERATOR ... enum ... enum ... enumMonday, August 1, 2011
  23. 23. 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 iteratorsMonday, August 1, 2011
  24. 24. Create Enumerator explicitly with a code block e = Enumerator.new do |y| y << “Frye” y << “Bender” y << “Leela” y << “Zoidberg” end •y is the yielder, an instance of Enumerator::Yielder • You don’t yield from the block, you only append to the yielderMonday, August 1, 2011
  25. 25. Attach an Enumerator to another object names = %w { Frye Bender Leela Zoidberg } e = names.enum_for(:select) • knows/learns how to implement #each from another object • we’re binding the Enumerator to the #select method of the names arrayMonday, August 1, 2011
  26. 26. Create Enumerator implicitly with blockless iterators names = %w { Frye Leela Bender } names.enum_for(:select) # => #<Enumerator: ["Frye", "Leela", "Bender"]:map> names.map # => #<Enumerator: ["Frye", "Leela", "Bender"]:map> • most iterators when called without a block return an Enumerator • our blockless iterator returned the same Enumerator as the enum_for approachMonday, August 1, 2011
  27. 27. BUT WHY DO WE CARE? ...USES?Monday, August 1, 2011
  28. 28. Add Enumerability to an existing 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) • Now we can use Enumerable methods on our ship objectMonday, August 1, 2011
  29. 29. Fine Grained Iteration scenes = %w{ credits opening climax end } e = scenes puts e.next puts e.next e.rewind puts e.next • An Enumerator is an object, it can maintain state • Think film reels, state machines, etc...Monday, August 1, 2011
  30. 30. CHAINING ENUMERATORS... ...HMMMMonday, August 1, 2011
  31. 31. 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 chainMonday, August 1, 2011
  32. 32. LAZY SLICE names = %w { Frye Bender Leela Zoidberg } names.each_slice(2).map do |first, second| “#{first} gets a slice & #{second} gets a slice” end • 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)Monday, August 1, 2011
  33. 33. MAP WITH INDEX...WTF? names = %w { Leela Bender Frye Zoidberg } names.map.with_index do |name, i| “#{name} has a rank #{i}” end • 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!)Monday, August 1, 2011
  34. 34. THE SET CLASSMonday, August 1, 2011
  35. 35. 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 moduleMonday, August 1, 2011
  36. 36. SET IS ENUMERABLE class Set include Enumerable #... def each block_given? or return enum_for(__method__) @hash.each_key { |o| yield(o) } self end end • Calls a block for each member of the set passing the member as a parameter • Returns an enumerator if no block is givenMonday, August 1, 2011
  37. 37. SET IS ENUMERABLE 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 end end • Actually uses Hash for implementing unique valuesMonday, August 1, 2011
  38. 38. SET IS ENUMERABLE class Set include Enumerable #... def include? @hash.include?(o) end alias member? include? end • Defines its own implementation of Enumerable methodsMonday, August 1, 2011
  39. 39. ARE YOU IN LOVE YET?Monday, August 1, 2011
  40. 40. THEN READ THIS • Thistalk was inspired by the AWESOME discussion of Enumerable by David A. Black • READ IT! SPREAD THE WORD!!!!Monday, August 1, 2011
  41. 41. THANK YOU! hamin harisamin harisamin.tumblr.comMonday, August 1, 2011

×