More Well Grounded Rubyist

Recently I got through Chapters 10, 11 and 12 in The Well-Grounded Rubyist.

11 was about regular expressions. I found out about the MatchData class, which I really like.

10 was about Enumerable and Enumerator. It is a chapter I will probably look at again many times in the future. There was a tweet from Evan Light in which he stated that after 6 years of Ruby, he now realizes that a lot of his problems can be solved by a careful reading of the doc page for Enumerable.

[9] pry(main)> [1,2,3,4,5,6,7,8,9,10].find{|n| n > 5}
=> 6
[10] pry(main)> [1,2,3,4,5,6,7,8,9,10].find_all{|n| n > 5}
=> [6, 7, 8, 9, 10]

So this is why ActiveRecord has find_by_SOMEFIELD (which returns first one) and find_all_by_SOMEFIELD (which returns all)
find_all is also called select

Enumerable.grep can filter/grep by content (as grep on command line does) or it can filter/grep by type. Pretty nice.

[15] pry(main)> colors = %w{red orange yellow green blue indigo violet}
=> ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]
[16] pry(main)> colors.grep(/o/)
=> ["orange", "yellow", "indigo", "violet"]
[17] pry(main)> miscellany = [75, "hello", 10...20, "goodbye"]
=> [75, "hello", 10...20, "goodbye"]
[18] pry(main)> the_third = miscellany[2]
=> 10...20
[19] pry(main)> the_third.class
=> Range
[20] pry(main)> miscellany.grep(String)
=> ["hello", "goodbye"]
[21] pry(main)> miscellany.grep(Range)
=> [10...20]
[22] pry(main)> miscellany.grep(fixnum)
NameError: undefined local variable or method `fixnum' for main:Object
from (pry):22:in `<main>'
[23] pry(main)> miscellany.grep(Fixnum)
=> [75]
[24] pry(main)> miscellany.grep('hello')
=> ["hello"]
[25] pry(main)> miscellany.grep(/hello/)
=> ["hello"]
[26] pry(main)> miscellany.grep(/ll/)
=> ["hello"]
[27] pry(main)> miscellany.grep(50..100)
=> [75]

Look up “case equality” ===

group by is pretty funky

[29] pry(main)> colors.group_by{|color|color.size}
=> {3=>["red"],
 6=>["orange", "yellow", "indigo", "violet"],
 5=>["green"],
 4=>["blue"]}

[31] pry(main)> colors.group_by{colors.grep(/o/)}
=> {["orange", "yellow", "indigo", "violet"]=>
  ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]}
[34] pry(main)> colors.group_by{|color|color =~ /o/}
=> {nil=>["red", "green", "blue"],
 0=>["orange"],
 4=>["yellow"],
 5=>["indigo"],
 2=>["violet"]}

Another thing I figured out is how to include one of my own Ruby files in pry or IRB:

pry -I ./

And then in pry:

require 'FileName.rb'

Enumerable.inject is also known as reduce (as in MapReduce) or “fold” in some functional languages

[1,2,3,4].inject(0) {|acc, n| acc + n}

In the block, n is the next element in the array. It seems that usually the first element in the block is the array element. It is called “reduce” because you are reducing the array to one value based on a repeated, cumulative operation. I think that “consolidate” might be a better name. It might be a bit verbose, but it would be clearer.