The Enumerable Module or How I Fell in Love with Ruby

41
THE ENUMERABLE MODULE or How I Fell In Love with Ruby! Haris Amin Cascadia Ruby Conf 2011 07/29/2011 Monday, August 1, 2011

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

Transcript of The Enumerable Module or How I Fell in Love with Ruby

Page 1: The Enumerable Module or How I Fell in Love with Ruby

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

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

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

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

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

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

THOUGHT TO MYSELF...

Arrays & Hashes

ARE FUN!!!!

Monday, August 1, 2011

Page 8: The Enumerable Module or How I Fell in Love with Ruby

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

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

• 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

BUT WHY IS ENUMERABLE SO...

SEXY!?

...

...

...

Monday, August 1, 2011

Page 12: The Enumerable Module or How I Fell in Love with Ruby

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

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

WATCH OUT FOR DR. ZOIDBERG’S TIPS

Monday, August 1, 2011

Page 15: The Enumerable Module or How I Fell in Love with Ruby

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

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

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

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

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

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

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

THE DELICIOUS ENUMERATOR... enum ... enum ... enum

Monday, August 1, 2011

Page 23: The Enumerable Module or How I Fell in Love with Ruby

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

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

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

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

BUT WHY DO WE CARE?

...USES?

Monday, August 1, 2011

Page 28: The Enumerable Module or How I Fell in Love with Ruby

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

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

CHAINING ENUMERATORS...

...HMMM

Monday, August 1, 2011

Page 31: The Enumerable Module or How I Fell in Love with Ruby

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

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

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

THE SET CLASS

Monday, August 1, 2011

Page 35: The Enumerable Module or How I Fell in Love with Ruby

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

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

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

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

ARE YOU IN LOVE YET?

Monday, August 1, 2011

Page 40: The Enumerable Module or How I Fell in Love with Ruby

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

THANK YOU!

hamin

harisamin

harisamin.tumblr.com

Monday, August 1, 2011