From: David Alan Black Date: 2002-07-08T21:06:53+09:00 Subject: Re: is there a better string.each? Hello -- On Mon, 8 Jul 2002, George Ogata wrote: > Couldn't we have separate methods (as suggested earlier) #bytes, #chars (or > #characters), #words (maybe), #lines, #pars (or #paragraphs) for String? > We could have identical methods for the IO class, so IOs and Strings can be > used interchangeably with these methods. These methods could be both used > to iterate over the object (when called with a block), or used to retrieve > an Array (not array!) of the elements we're interested in (when called > without a block). E.g.: > > s = "abc\ndef\nghi" > s.lines >> ["abc", "def", "ghi"] > a = [] > s.lines do {|s| a << (s + 'xyz')} >> nil (or maybe something else) > s >> ["abcxyz", "defxyz", "ghixyz"] > > Thus, io.lines &proc has the same effect as io.lines.each &proc (though > would hopefully require less memory when say, reading in a large file, > since the former doesn't need to read the whole thing into a gigantic Array > first). > > Now, what about #each? Well, we've made it essentially useless for calling > directly (since the others are more readable and unambiguous (agree?)). > But there's still the interaction of String and IO with the Enumerable > mixin. What about this?: > > We have methods corresponding to the iterator/collector methods to set the > one that #each points to: #useBytes, #useChars (or #useCharacters), > #useWords, #useLines, #usePars (or #useParagraphs). > > These could be defined in their own mixin module: > > Module StringProcessing > def useBytes > class << self > alias each bytes > end > end [same for Chars, Lines, etc] > These would change the behaviour of #each for the String or IO instance > they're called. E.g.: > > s = "abc\ndef\nghi" > s.useChars > s.collect {|char| frob char} # iterates over chars > s.useLines > s.collect {|line| frob line} # now it iterates over lines Personally I'm much happier doing: s.split("").collect {|char| ... } Maybe it's the camelCase that's putting me off :-) but I think it's more just that this seems like a new, parallel-universe way of doing things Ruby already does with record separators and #split parameters and so forth. (I'm not saying there isn't room to debate how those things work... just that the above examples seem stylistically and design-ly very different.) > The default behaviour would be to iterate over lines, so as to be backward > compatible. Well, except for my little, implicit wish that the record > separators would be removed automatically. E.g., I'd rather > "abc\ndef".lines would return ["abc", "def"] than ["abc\n", "def"]. But I > guess that's another war... Still, even if the record separators stay, > this'd be a pretty flexible String/IO model, wouldn't it? > > Thoughts? My main thought is that I wish I could get Ruby Behaviors to work fully :-) (http://www.superlink.net/~dblack/ruby/behaviors) I remain convinced that Ruby could/can/should lend itself to tremendous flexibility and even-handedness in many matters, without changes to the core language. The Behaviors package as it stands doesn't fully let the genie out of the bottle... but maybe that will come. (Anyone seen David Simmons lately? :-) David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav