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