Object loops and what they return

Eric Mahurin wrote:
> Enumerable says nothing about the return value or each.
> Array.each says it returns an Array, but not what's in that
> Array. Before testing, I was thinking it might be the same
as
> map/collect. The integer loops also say they return an
> integer, but not what it is.

You seem to be not so much interested in whether or not
people use this
feature, as instead convincing them that they shouldn't use
them,
because you'd like to see the feature go away.

(Which is fine...expressing one's opinions and attempting to
sway
others' it one fine use of the mailing list :slight_smile:

I was doing both. I don't like the current behavior and would
like to propose a change, but need to know what the usage is to
see how feasible making a change would be (rendering some code
incompatible).

However, I fail to see as valid the argument that we should
not be
using a feature just because the documentation is incomplete.
Instead,
the documentation should be fixed.

There may certainly to be some side-effects of idiosyncracies
of the
language implementation upon which one should not rely, but
that
specific self return value of certain methods smells far more
like an
intentional feature than a bug.

Your argument that they should return nil for consistency
certainly has
some merit. I counter-argue that if you're always going to
return the
same value from a method, returning the receiver is usually
preferable
over returning nil.

I vote: don't take away my feature just because you don't
like it, and
don't like that I use chaining across blockths which (to

some)

looks
ugly. :slight_smile:

If each, each_with_index, downto, upto, step, times, etc
returned nil instead of the original object, it wouldn't be
that difficult to change the code that depended on the original
object returning functionality. For code that would rather
have nil returned, the current functionality forces one to make
a new method for one of these loops or use loop/while/until.

To give more examples, here is how you could write stuff (with
a nil return) like what is in Enumerable (and Array) withod the
need of any more methods:

find(&b): enum.each {|o| break(o) if b.call(o) } -> o or nil
???(&b): enum.each {|o| r=b.call(o) and break(r) } -> r or nil
include?(x): enum.each {|o| break(true) if x==o } -> true or
nil
index(x): enum.each_with_index {|o,i| break(i) if x==o } -> i
or nil
index(&b): enum.each_with_index {|o,i| break(i) if b.call(o) }
-> i or nil
find(&b): m.downto(n) {|i| break(i) if b.call(i) } -> i or nil
...

If each and each_with_index returned nil, you wouldn't need
find, include, and index because you could accomplish the same
thing with each and each_with_index and just 2 more words:
break if. And of course you could do a lot more using whatever
code you want. Another example is that the latest addition to
Array.index to take a block (1.9?) wouldn't be needed. To me,
all of the above code is clearer than find, include, index
because the exact condition checked and what is returned is
shown.

Also, making this change would make these work just like
loop/while/until where they return nil unless a break (with a
value) is done. I think that functionality makes sense and is
useful.

I may have lost this battle already as it appears as though
some are using the current functionality (that doesn't add too
much value). It just may be too late to change this API. But
I wanted to give my 2 cents.

Yahoo! Mail
Stay connected, organized, and protected. Take the tour:
http://tour.mail.yahoo.com/mailtour.html

···

--- Phrogz <gavin@refinery.com> wrote:

I just do not see any benefit in the approach; the current
implementation allows method chaining and a change would
quite possibly break some of code. Furthermore, I would
hypothetize that rewriting your example cases would be
simpler than the other way around. For example, one would
likely use a method like #find rather than #each combined
with a #break if one were to attempt to find a certain
value.

E

···

Le 12/5/2005, "Eric Mahurin" <eric_mahurin@yahoo.com> a écrit:

--- Phrogz <gavin@refinery.com> wrote:

Eric Mahurin wrote:
> Enumerable says nothing about the return value or each.
> Array.each says it returns an Array, but not what's in that
> Array. Before testing, I was thinking it might be the same
as
> map/collect. The integer loops also say they return an
> integer, but not what it is.

You seem to be not so much interested in whether or not
people use this
feature, as instead convincing them that they shouldn't use
them,
because you'd like to see the feature go away.

(Which is fine...expressing one's opinions and attempting to
sway
others' it one fine use of the mailing list :slight_smile:

I was doing both. I don't like the current behavior and would
like to propose a change, but need to know what the usage is to
see how feasible making a change would be (rendering some code
incompatible).

However, I fail to see as valid the argument that we should
not be
using a feature just because the documentation is incomplete.
Instead,
the documentation should be fixed.

There may certainly to be some side-effects of idiosyncracies
of the
language implementation upon which one should not rely, but
that
specific self return value of certain methods smells far more
like an
intentional feature than a bug.

Your argument that they should return nil for consistency
certainly has
some merit. I counter-argue that if you're always going to
return the
same value from a method, returning the receiver is usually
preferable
over returning nil.

I vote: don't take away my feature just because you don't
like it, and
don't like that I use chaining across blockths which (to

some)

looks
ugly. :slight_smile:

If each, each_with_index, downto, upto, step, times, etc
returned nil instead of the original object, it wouldn't be
that difficult to change the code that depended on the original
object returning functionality. For code that would rather
have nil returned, the current functionality forces one to make
a new method for one of these loops or use loop/while/until.

To give more examples, here is how you could write stuff (with
a nil return) like what is in Enumerable (and Array) withod the
need of any more methods:

find(&b): enum.each {|o| break(o) if b.call(o) } -> o or nil
???(&b): enum.each {|o| r=b.call(o) and break(r) } -> r or nil
include?(x): enum.each {|o| break(true) if x==o } -> true or
nil
index(x): enum.each_with_index {|o,i| break(i) if x==o } -> i
or nil
index(&b): enum.each_with_index {|o,i| break(i) if b.call(o) }
-> i or nil
find(&b): m.downto(n) {|i| break(i) if b.call(i) } -> i or nil
...

If each and each_with_index returned nil, you wouldn't need
find, include, and index because you could accomplish the same
thing with each and each_with_index and just 2 more words:
break if. And of course you could do a lot more using whatever
code you want. Another example is that the latest addition to
Array.index to take a block (1.9?) wouldn't be needed. To me,
all of the above code is clearer than find, include, index
because the exact condition checked and what is returned is
shown.

Also, making this change would make these work just like
loop/while/until where they return nil unless a break (with a
value) is done. I think that functionality makes sense and is
useful.

I may have lost this battle already as it appears as though
some are using the current functionality (that doesn't add too
much value). It just may be too late to change this API. But
I wanted to give my 2 cents.

--
template<typename duck>
void quack(duck& d) { d.quack(); }