read
Basically Enumerable mixin gives collection classes a variety of traverse, search, sort methods.
Understanding ruby blocks
Blocks are statements of code written in ruby. one can take them as similar to c language macro’s
Different ways to define blocks
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>a = proc do
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> puts "hello"
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'>end
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'>a.call #=> hello
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'>b = lambda do |u|
</div></div><div data-line='7' class='code-highlight-row numbered'><div class='code-highlight-line'> puts "hello #{u}"
</div></div><div data-line='8' class='code-highlight-row numbered'><div class='code-highlight-line'>end
</div></div><div data-line='9' class='code-highlight-row numbered'><div class='code-highlight-line'>b.call('sandip')#=> hello sandip
</div></div><div data-line='10' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='11' class='code-highlight-row numbered'><div class='code-highlight-line'>c = proc {|user| puts user }
</div></div><div data-line='12' class='code-highlight-row numbered'><div class='code-highlight-line'>c.call('sandip') #=> sandip</div></div></pre></div>
Passing block to enumerator
Lets assume we have collection array of strings and we want to print it
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>a = ['hi', 'sandip', 'how', 'you', 'doing', '?']
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'>=> ["hi", "sandip", "how", "you", "doing", "?"]
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'>a.each {|w| puts w }
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'>q = proc {|w| puts w }
</div></div><div data-line='7' class='code-highlight-row numbered'><div class='code-highlight-line'>=> #<Proc:0x00007f9d2be13140@(irb):89>
</div></div><div data-line='8' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='9' class='code-highlight-row numbered'><div class='code-highlight-line'>a.each(&q) #=>
</div></div><div data-line='10' class='code-highlight-row numbered'><div class='code-highlight-line'>hi
</div></div><div data-line='11' class='code-highlight-row numbered'><div class='code-highlight-line'>sandip
</div></div><div data-line='12' class='code-highlight-row numbered'><div class='code-highlight-line'>how
</div></div><div data-line='13' class='code-highlight-row numbered'><div class='code-highlight-line'>you
</div></div><div data-line='14' class='code-highlight-row numbered'><div class='code-highlight-line'>doing
</div></div><div data-line='15' class='code-highlight-row numbered'><div class='code-highlight-line'>?
</div></div><div data-line='16' class='code-highlight-row numbered'><div class='code-highlight-line'> </div></div><div data-line='17' class='code-highlight-row numbered'><div class='code-highlight-line'>a.map{|r| q.call(r)} #=>
</div></div><div data-line='18' class='code-highlight-row numbered'><div class='code-highlight-line'>hi
</div></div><div data-line='19' class='code-highlight-row numbered'><div class='code-highlight-line'>sandip
</div></div><div data-line='20' class='code-highlight-row numbered'><div class='code-highlight-line'>how
</div></div><div data-line='21' class='code-highlight-row numbered'><div class='code-highlight-line'>you
</div></div><div data-line='22' class='code-highlight-row numbered'><div class='code-highlight-line'>doing
</div></div><div data-line='23' class='code-highlight-row numbered'><div class='code-highlight-line'>?</div></div></pre></div>
Understanding symbol#to_proc
Symbol has method to_proc
which converts symbol to block where symbol is taken as method to be executed on first argument of proc
** How to_proc got implemented inside Symbol class**
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>class Symbol
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'> def to_proc
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'> Proc.new { |*args| args.shift.send(self, *args) }
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'> end
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'>end</div></div></pre></div>
Lets have some examples:
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>v = :even?.to_proc # equivalent to proc {|a| a.even?}
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'>#=> #<Proc:0x00007f9d2bddcb90@(irb):97>
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'>q = [1, 2, 3, 5, 67]
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'>q.map(&v) => [false, true, false, false, false]</div></div></pre></div>
Is there any shortcut?
Yes, there is shortcut to have block passed to enumerators on the fly using ampersand followed by colon (i.e. symbol)
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>q = [1, 2, 3, 5, 67]
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'>q.map(&:even?) <=> q.map(&:even?.to_proc)
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'>q.map(&:even?.to_proc)
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'>#=> [false, true, false, false, false]
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'>q.map(&:even?)
</div></div><div data-line='6' class='code-highlight-row numbered'><div class='code-highlight-line'>#=> [false, true, false, false, false]</div></div></pre></div>
Some handy examples
<div class='code-highlight'><pre class='code-highlight-pre'><div data-line='1' class='code-highlight-row numbered'><div class='code-highlight-line'>[1, 2, 3, 5, 67].inject(&:+) #=> 78
</div></div><div data-line='2' class='code-highlight-row numbered'><div class='code-highlight-line'>[1, 2, 3, 5, 67].inject(:+) #=> 78
</div></div><div data-line='3' class='code-highlight-row numbered'><div class='code-highlight-line'>[1, 2, 3, 5, 67].any?(&:even?) #=> true
</div></div><div data-line='4' class='code-highlight-row numbered'><div class='code-highlight-line'>[1, 2, 3, 5, 67].detect(&:even?) #=> 2
</div></div><div data-line='5' class='code-highlight-row numbered'><div class='code-highlight-line'>['ruby', 'on', 'rails'].map(&:upcase) #=> ["RUBY", "ON", "RAILS"]</div></div></pre></div>