inside enumerable
DESCRIPTION
A look at the Enumerable module in Ruby. What it is, how it works and what you can do with it.TRANSCRIPT
![Page 1: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/1.jpg)
Inside Enumerable
Inside Enumerable
Mike BowlerGargoyle Software Inc.
Mike BowlerGargoyle Software Inc.
![Page 2: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/2.jpg)
AgendaAgenda
1.What is Enumerable?
2.What can you do with it?
3.How does it do that?
![Page 3: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/3.jpg)
What is it?What is it?
It’s a group of related methods all having to do with collections
It’s the interesting part behind Array, Set, Hash and Range
It’s a Module (often called a mixin)
![Page 4: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/4.jpg)
hash = {:a => 1, :b => 2}hash.collect do |key, value| value * 4end
[4,8]
[4,8,12]
[4,8,12]
array = [1,2,3]array.collect do |value| value * 4end
range = 1..3range.collect do |value| value * 4end
![Page 5: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/5.jpg)
hash = {:a => 1, :b => 2}hash.collect do |key, value| value * 4end
array = [1,2,3]array.collect do |value| value * 4end
range = 1..3range.collect do |value| value * 4end
module Enumerable def collect ... endend
![Page 6: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/6.jpg)
multiple inheritancemultiple inheritance
![Page 7: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/7.jpg)
mixinsmixins
![Page 8: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/8.jpg)
MixinsMixins
Cannot be instantiatedCan be mixed in
![Page 9: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/9.jpg)
Mixins usually don’t stand alone
Mixins usually don’t stand alone
Typically...
mixins aren’t completely self-contained
they rely on certain methods being present on the class they are mixed into
This isn’t mandatory but is very common
Let’s look at an example...
![Page 10: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/10.jpg)
Enumerable requires each()
Enumerable requires each()
[1,2,3].collect {|i| i*2} [2,4,6]
![Page 11: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/11.jpg)
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
Enumerable.collectEnumerable.collectmodule Enumerable def collect array = [] each do |a| array << yield(a) end array endend
![Page 12: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/12.jpg)
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
Enumerable.collectEnumerable.collect
![Page 13: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/13.jpg)
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
Enumerable.collectEnumerable.collect
![Page 14: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/14.jpg)
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
Enumerable.collectEnumerable.collect
![Page 15: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/15.jpg)
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
Enumerable.collectEnumerable.collect
![Page 16: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/16.jpg)
class Foo include Enumerable
def each yield 1 yield 2 yield 3 endend
Foo.new.collect do |num| num * 2end
module Enumerable def collect array = [] each do |a| array << yield(a) end array endend
Enumerable.collectEnumerable.collect
Result[2,4,6]
![Page 17: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/17.jpg)
Comparisonoperator
Required methodsRequired methods
collect() would not have worked if Foo hadn’t declared each()
All methods in Enumerable require each()
A couple also require <=>
min(), max(), sort()
![Page 18: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/18.jpg)
Enumerable methods
Enumerable 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
![Page 19: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/19.jpg)
any?any?
[1,2,3,4].any? {|a| a > 2}
Returns true if this block...
...returns true for any of these
values
![Page 20: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/20.jpg)
all?all?
[1,2,3,4].all? {|a| a > 2}
Returns true if this block...
...returns true for ALL of these
values
![Page 21: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/21.jpg)
collect, mapcollect, map
“Returns a new array with the results of running block once for every element in enum”
map is an alias for collect
[1,2,3].collect {|i| i*2} [2,4,6]
![Page 22: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/22.jpg)
find, detectfind, detect
find(ifnone = nil) {| obj | block } => obj or nil
Passes each entry in enum to block. Returns the first for which block is not false. If no object matches, calls ifnone and returns its result when it is specified, or returns nil
detect is an alias for find
![Page 23: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/23.jpg)
find_all, selectfind_all, select
find_all {| obj | block } => array
Returns an array containing all elements of enum for which block is not false
select is an alias for find_all
![Page 24: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/24.jpg)
Case equality
grepgrepgrep(pattern) => array
Returns an array of every element in enum for which Pattern === element. If the optional block is supplied, each matching element is passed to it, and the block‘s result is stored in the output array
![Page 25: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/25.jpg)
Case equalityCase equalityFor most objects, === is the same as ==
Caseequality
Regularequality
![Page 26: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/26.jpg)
Case equalityCase equality
case myvar when 1..50 # do something when 51 # do something when /^\d+$/ # do somethingend
Within the range
This exact number
Matches this regular expression
Different kind of equality as aconvenience in case statements
![Page 27: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/27.jpg)
Case equality in grepCase equality in grep
[1,2,3].grep(1..50)
[1,2,3].grep(51)
[1,2,3].grep(/^\d+$/)
Within the range
This exact number
Matches this regular expression
![Page 28: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/28.jpg)
Wrap upWrap up
Enumerable is already mixed into all the core collections
You can mix it into any of your classes so long as you implement each()
It provides all kinds of useful methods to walk across the collections and get information out of them
![Page 29: Inside Enumerable](https://reader034.vdocuments.us/reader034/viewer/2022042518/54bf76a54a7959a9278b4603/html5/thumbnails/29.jpg)
Shameless PlugShameless Plug
I can help you with your Ruby and/or Rails projects. Ask me how.
Mike [email protected] (company)www.SphericalImprovement.com (blog)