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
Inside Enumerable
Inside Enumerable
Mike BowlerGargoyle Software Inc.
Mike BowlerGargoyle Software Inc.
AgendaAgenda
1.What is Enumerable?
2.What can you do with it?
3.How does it do that?
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)
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
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
multiple inheritancemultiple inheritance
mixinsmixins
MixinsMixins
Cannot be instantiatedCan be mixed in
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...
Enumerable requires each()
Enumerable requires each()
[1,2,3].collect {|i| i*2} [2,4,6]
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
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
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
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
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
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]
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()
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
any?any?
[1,2,3,4].any? {|a| a > 2}
Returns true if this block...
...returns true for any of these
values
all?all?
[1,2,3,4].all? {|a| a > 2}
Returns true if this block...
...returns true for ALL of these
values
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]
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
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
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
Case equalityCase equalityFor most objects, === is the same as ==
Caseequality
Regularequality
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
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
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
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)