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
Post a Comment