enumerable/folding_and_matching.rb
tests/_examples/enumerable/folding_and_matching.rb in the metorex repository.
# inject folds a walk, either through a block or through an operator named by
# a Symbol or a String.
class Numerous
include Enumerable
def initialize(*list)
@list = list
end
def each
@list.each { |value| yield(value) }
end
end
numbers = Numerous.new(1, 2, 3, 4)
p numbers.inject { |total, value| total + value }
p numbers.inject(10) { |total, value| total + value }
p numbers.inject(:+)
p numbers.inject("+")
p numbers.inject(10, :-)
p numbers.reduce(:*)
p [1, 2, 3, 4].inject(:+)
p [1, 2, 3, 4].inject(10, :-)
# A name that is neither a Symbol nor a String is asked for one through
# to_str, and anything else is a TypeError.
class Minus
def to_str
"-"
end
end
p numbers.inject(10, Minus.new)
begin
numbers.inject(10, Object.new)
rescue TypeError => error
p error.message.include?("is not a symbol nor a string")
end
begin
[1, 2].inject
rescue ArgumentError => error
p error.message
end
# A block that grows the array while inject walks it reaches what it added.
grown = [1, 2, 3]
seen = []
grown.inject(nil) do |_, value|
seen.push(value)
grown.push(value + 10) if value < 4
nil
end
p seen
# grep keeps the elements a pattern matches, grep_v the rest, and a block
# maps what is kept.
words = Numerous.new("apple", "banana", "cherry")
p words.grep(/an/)
p words.grep_v(/an/)
p words.grep(/rr/) { |word| word.upcase }
p Numerous.new(1, "two", :three, 4).grep(Integer)
# A parenthesized assignment names the receiver of a singleton definition.
class Matchers
def odd_matcher
def (@odd = Object.new).===(other)
other.odd?
end
@odd
end
end
matcher = Matchers.new.odd_matcher
p [1, 2, 3, 4].grep(matcher)
p [1, 2, 3, 4].grep_v(matcher)
Output:
10
20
10
10
0
24
10
0
0
true
"wrong number of arguments (given 0, expected 1)"
[1, 2, 3, 11, 12, 13]
["banana"]
["apple", "cherry"]
["CHERRY"]
[1, 4]
[1, 3]
[2, 4]