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

The Enumerable Module or How I Fell in Love with Ruby

Embed Size (px)

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

Citation preview

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