From: Brian Candler Date: 2004-10-21T04:47:59+09:00 Subject: Re: each with separator > Yes of course, but it's not imperative and I'm looking for an imperative > version like the Smalltalk one. My inclination would be to start simple: module Enumerable def each_with_separator(sepblk) first = true each do |item| sepblk.call unless first first = false yield item end end end [1,2,3].each_with_separator(proc { puts "-" }) {|obj| puts obj } But it's admittedly a bit ugly passing two blocks in this way. If you want you can create an intermediate object which holds the separator block and performs the iteration: module Enumerable def separate_by(&blk) Separator.new(self,blk) end class Separator include Enumerable # eat your own tail :-) def initialize(thing,sepblk) @thing = thing @sepblk = sepblk end def each first = true @thing.each do |item| @sepblk.call unless first first = false yield item end end end end [1,2,3].separate_by { puts "-" }.each {|obj| puts obj} I'm not sure if that's a general enough pattern for you. For example, an Enumerable::Separator is enumerable, but you can't use 'collect' to collect the objects and the separators. Perhaps you want to 'yield' the separator instead? module Enumerable def separate_by2(separator) Separator2.new(self,separator) end class Separator2 include Enumerable def initialize(thing,separator) @thing = thing @separator = separator end def each first = true @thing.each do |item| yield @separator unless first first = false yield item end end end end [1,2,3].separate_by2("-").each {|obj| puts obj} a = [1,2,3].separate_by2("-").collect {|obj| obj * 2} #=> returns [2, "--", 4, "--", 6] Regards, Brian.