module - implement `each` for Enumerable mixin in Ruby -


i'm learning magic of enumerable in ruby. i've heard 1 have include enumerable , implement each method , can have power of enumerable class.

so, thought implementing own custom class foo practice. looks below:

class foo   include enumerable    def initialize numbers     @num = numbers   end    def each     return enum_for(:each) unless block_given?     @num.each { |i| yield + 1 }   end end 

this class takes array , each works similar array#each. here's difference:

>> f = foo.new [1, 2, 3] => #<foo:0x00000001632e40 @num=[1, 2, 3]> >> f.each { |i| p } 2 3 4 => [1, 2, 3]   # why this? why not [2, 3, 4]? 

everything works expect except 1 thing last statement. know return value shouldn't [2, 3, 4]. there way make [2, 3, 4].

also please comment on way have implemented each. if there's better way please let me know. @ first in implementation didn't had line return enum_for(:each) unless block_given? , wasn't working when no block provided. borrowed line somewhere , please tell me whether right way handle situation or not.

the return value of each supposed receiver, i.e. self. returning result of calling @num.each. now, said, each returns self, ergo @num.each returns @num.

the fix simple: return self:

def each   return enum_for(:each) unless block_given?   @num.each { |i| yield + 1 }   self end 

or, possibly bit more rubyish:

def each   return enum_for(:each) unless block_given?   tap { @num.each { |i| yield + 1 }} end 

[actually, of ruby 1.8.7+, each supposed return enumerator when called without block, correctly handling that. tip: if want implement optimized versions of of other enumerable methods overriding them, or want add own enumerable-like methods similar behavior, original ones, going cut&paste exact same line of code on , over, , @ 1 point, accidentally forget change name of method. if replace line return enum_for(__callee__) unless block_given?, don't have remember changing name.]


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -