Hi --

On Sat, 21 Oct 2006, Yukihiro Matsumoto wrote:

> Hi,
>
> In message "Re: String not enumerable, what about IO? (was Re: Symbol < String in Ruby > 1.8)"
>    on Sat, 21 Oct 2006 11:29:21 +0900, dblack / wobblini.net writes:
>
> |> Extending that logic do you also want, say:
> |>
> |>  {:a => :b, :c => :d}.each_key => ERROR NO BLOCK GIVEN
> |
> |Yes.  I don't like each* without a block (but I think I'm fighting a
> |losing battle).
>
> I am (sort of) with you for this issue though.
>
> |> And I don't see it as Arrays competing with Enumerators.  Arrays as
> |> jack-of-all-trades collections are perhaps overused in Ruby.
> |
> |I mean specifically that there seems to be a winner-take-all
> |competition for the lines/chars/bytes/* (plural objects) namespace.
>
> Can you rephrase?  I didn't get your intention here.

Just that I think that if we need multiple things to happen -- an
array vs. an enumerator being returned, etc. -- then there should be
multiple method names, as opposed to one set of method names and one
decision as to what they return.  (Kind of just a reiteration of the
basic issue.)

> |Yes -- so let's have methods that sound like they're returning
> |Enumerators :-) I don't want arrays to have a rest when the
> |overwhelming thrust of the method-name semantics is array-like.  I'm
> |not looking forward to seeing (or writing, for that matter) book
> |passages like this:
> |
> |   You'd think that calling lines would give you all the lines in the
> |   string, stored in a collection that you can print, inspect, and/or
> |   index.  However, Ruby actually performs a kind of interception: what
> |   you get is not an ordered collection of lines, but a kind of handle
> |   on the collection that lets you perform some, but by no means all,
> |   of the operations you might expect.
> |
> |etc.  (And this isn't just a "let's keep it simple for nubies" thing.)
>
> Calling lines gives you lines in the strings contained in an object,
> which happens to be an Enumerator now.  I don't think I get your
> point.  What is your point among the following?
>
>  * lines should return an array (not anything else)
>  * lines should split a string into lines eagerly.
>  * lines should not take an block.
>  * an enumerator is not good enough for lines, more array-like object
>    will do (even if it evaluates lazily).
>
> I personally don't care if lines evaluate lazily.  That's perhaps
> because I read the book on Haskell recently.

I think that plural-noun names should return something that behaves in
every possible way like a collection of the noun-items:

   lines = string.lines
   puts lines               # you see the lines themselves
   lines[3] = "hi"          # you can index the collection
   lines.select {|l| ... }  # iteration

etc.  This could be a lazy array-like object, for efficiency.

Then, if you wanted an enumerator instead, you would either:

   1. ask for one from the array(-like object):
        string.lines.to_enum (or something)
   2. ask for one from the original object:
        string.enumerator (or something)
   3. ask for one from the original object, with some slightly
      nicer method name:
        string.by_lines
        string.line_wise
        string.as_lines
        (etc.)

Mainly I don't want to see an extra step to get from a plural-noun
method to an array:

   string.lines.to_a

I think the lazy array-like thing could be very productive here.


David

-- 
                   David A. Black | dblack / wobblini.net
Author of "Ruby for Rails"   [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog)        [2] | Co-director, Ruby Central, Inc.   [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com    | [4] http://www.rubycentral.org