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