From: Ross Bamford Date: 2006-03-21T19:08:54+09:00 Subject: Re: iterate chars in a string On Tue, 2006-03-21 at 18:47 +0900, Robert Dober wrote: > Sorry Robert but I do not think I made myself too clear > > we now about each_byte and I already combined your #chr and String#each_byte > > so we had already established > > "Ty Mr. Klemme".each_byte { |b| puts b.chr } > > which is pretty elegant, don't you agree? > So Enumerators are not needed. > Duck typing? require 'enumerator' def just_iterate(obj) obj.each { |e| p e } end just_iterate("abc") # (prints) "abc" just_iterate("abc".enum_for(:each_byte)) # (prints) 97 # 98 # 99 > Now after that we switched discussing the behaviour of String#each and I > *really* feal that String#each should us give that kind of behaviour. > As I see that a lot of people think that the current behaviour of > String#each is a good one, and changing it would not be an option anyway I > thaught that the only solution would be to enhance the behaviour of > String#each. > The idea for that behaviour comes from Ruby itself (look at IO#gets) > > then > > "Ty Mr. Klemme".each_byte { |b| puts b.chr } > > would be the same as > > "Ty Mr. Klemme".each( 1 ) { |b| puts b } > > There is always more than one way to do it ;) Umm, there's *already* more than one way to do it :) But Enumerator really is a very useful class: "abc\ndef\nghi\njkl".each { |e| p e } # "abc\n" # "def\n" # "ghi\n" # "jkl" "abc\ndef\nghi\njkl\n".enum_for(:each_byte).each { |e| p e.chr } # "a" # "b" # "c" # "\n" # "d" # "e" # etc. "abc\ndef\nghi\njkl\n".enum_slice(2).each { |e| p e } # ["abc\n", "def\n"] # ["ghi\n", "jkl\n"] "abc\ndef\nghi\njkl\n".enum_for(:each_byte).enum_slice(2).each { |e| p e } # [97, 98] # [99, 10] # [100, 101] And crucially: "abc\ndef\nghi\njkl\n".enum_for(:each_byte).enum_slice(2).map do |(a,b)| (a + b).chr end # => ["\303", "m", "\311", "p", "\317", "s", "\325", "v"] How would map and other Enumerable methods work if 'each' needed arguments? -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk