Object loops and what they return

That sure looks ugly. I don't see any advantage of this over:

my_array.each do |item|
   puts "item"
end
if my_array.empty?
   puts "(no items found)"
end

What you have below doesn't look to readable and it is using
undocumented behavior (the docs don't say what each returns
only that it is an enumeration). In ruby 1.6 docs, it says
that each_with_index returns nil and now it returns the object.

···

Yes. Not often, but occasionally the return value is useful.

For example, there was a solution like this posted to the
rails mailing list, on how to iterate over all the items in a
record, or print out a 'no records found' type line if none
existed:

if my_array.each do |item|
   puts "item"
end.empty?
   puts "(no items found)"
end

________________________________

From: Eric Mahurin [mailto:eric_mahurin@yahoo.com]
Sent: Wed 5/11/2005 3:31 PM
To: ruby-talk ML
Subject: Re: object loops and what they return

> > Consider these loops:
> >
> > <object>.<loop-method> { <code> }
> >
> > where loop method is each, each_with_index, upto, downto,
> step,
> > and probably others.
> >
> > Although it is not documented, all of these look to
return
> the
> > origninal object (collection or int). Does anybody find
> this
> > useful?? If not, I would propose that these return nil
> just
> > like loop, while, until, begin/end while, and begin/end
> until.
> > I've never found the return value of these methods
useful,
> but
> > I have found the the built-in loops returning nil useful.
> Here
> > are a couple:
> >
> > # find first index where you find the object obj in array
> > index = array.each_with_index do |i,x|
> > break(i) if obj.equal?(x)
> > end
> >
> > # find last index where you find the object obj in array
> > index = (array.size-1).downto(0) do |i,x|
> > break(i) if obj.equal?(x)
> > end
>
> >> a=%w{a b c d e f g ab c}
> => ["a", "b", "c", "d", "e", "f", "g", "ab", "c"]
> >> a.index "c"
> => 2
> >> a.rindex "c"
> => 8
> >> a.index "foo"
> => nil

I was wanting to compare the objects with equal? (compares
object ids) not == (what index/rindex use).

> > The problem with the above now is that index will be the
> loop
> > object (array and array.size-1 from above) when you don't
> find
> > the obj. Instead of the above, I end up using old-style
> loops
> > to accomplish what I want.
> >
> > With "each" returning nil, you can also see that many of
> the
> > derived loops in Enumerable become trival almost to where
> you
> > don't need them.
>
> Interesting aspect. I assume the return behavior is from a
> time where break
> could not return a value so your constructions weren't
> possible.
>
> Typically I put such functionality into methods and then I
> use "return" to
> short circuit:
>
> module Enumerable
> def find_pos(x)
> each_with_index {|e,i| return i if x == e}
> nil
> end
>
> def find_cond
> each_with_index {|e,i| return i if yield e}
> nil
> end
> end

The loops I describe above were in some method. I didn't
want
to create a new method just for those loops. That would be
kind of silly. I used traditional loops instead. Also, with
what I am proposing you wouldn't need the "nil" in the above
2
methods.

Does anybody find a use for these loop methods returning the
original object (undocumented) instead of nil (like other
loops)? If not, I would like to make an RCR for this.

__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail

__________________________________
Yahoo! Mail Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http://mobile.yahoo.com/learn/mail

Eric Mahurin wrote:

That sure looks ugly. I don't see any advantage of this over:

my_array.each do |item|
   puts "item"
end
if my_array.empty?
   puts "(no items found)"
end

*shrug* I personally prefer what I posted over this. (I tend to use {
and } for blocks instead of begin/end in my own code because IMHO it
visually groups it better, but I used begin/end here since that seems
to be the emerging multi-line choice of the community.)

What you have below doesn't look to readable and it is using
undocumented behavior (the docs don't say what each returns
only that it is an enumeration). In ruby 1.6 docs, it says
that each_with_index returns nil and now it returns the object.

As I noted in another response, a lack of documentation calls for
fixing the documentation (as is needed in more than a few places in
Ruby), not for not using the method fully.

And that the behavior of this--and other like-minded--methods has
changed between 1.6 and 1.8 is not unique among aspects of Ruby. Just
'cause it changed, don't mean it broke. :slight_smile:

Hi --

···

On Thu, 12 May 2005, Phrogz wrote:

As I noted in another response, a lack of documentation calls for
fixing the documentation (as is needed in more than a few places in
Ruby), not for not using the method fully.

See my earlier posts -- ri does document these return values.

David

--
David A. Black
dblack@wobblini.net

I just wanted to throw in that I'm in the camp of people who use begin
end when the side effect is important and braces when the return value
is important. This conveys more meaning on a causual glance. I.e.

print "100!"
puts (1..100).inject(1) { | r, i |
  r*i
}

(1..100).inject(1) do | r, i |
  puts "#{i}! = #{r = r*i}"
end

regards,

Brian Schröder

···

On 12/05/05, Phrogz <gavin@refinery.com> wrote:

Eric Mahurin wrote:
> That sure looks ugly. I don't see any advantage of this over:
>
> my_array.each do |item|
> puts "item"
> end
> if my_array.empty?
> puts "(no items found)"
> end

*shrug* I personally prefer what I posted over this. (I tend to use {
and } for blocks instead of begin/end in my own code because IMHO it
visually groups it better, but I used begin/end here since that seems
to be the emerging multi-line choice of the community.)
[snip]

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

I had no idea that there was such a camp. I like that.

Can I come hang out in your camp? I'll bring my own sleeping bag and marshmallows.

···

On May 12, 2005, at 1:48 AM, Brian Schröder wrote:

On 12/05/05, Phrogz <gavin@refinery.com> wrote:

I tend to use {
and } for blocks instead of begin/end in my own code because IMHO it
visually groups it better, but I used begin/end here since that seems
to be the emerging multi-line choice of the community.)

I just wanted to throw in that I'm in the camp of people who use begin
end when the side effect is important and braces when the return value
is important.

In this case you're welcome. I know I read this in two independent
blog entries, but I can't find them now. So I imagine i do not really
own this camping site :wink:

best regards,

Brian

···

On 12/05/05, Gavin Kistner <gavin@refinery.com> wrote:

On May 12, 2005, at 1:48 AM, Brian Schröder wrote:
> On 12/05/05, Phrogz <gavin@refinery.com> wrote:
>> I tend to use {
>> and } for blocks instead of begin/end in my own code because IMHO it
>> visually groups it better, but I used begin/end here since that seems
>> to be the emerging multi-line choice of the community.)
>
> I just wanted to throw in that I'm in the camp of people who use begin
> end when the side effect is important and braces when the return value
> is important.

I had no idea that there was such a camp. I like that.

Can I come hang out in your camp? I'll bring my own sleeping bag and
marshmallows.

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Brian Schröder wrote:

I tend to use {
and } for blocks instead of begin/end in my own code because IMHO
it visually groups it better, but I used begin/end here since that
seems to be the emerging multi-line choice of the community.)

I just wanted to throw in that I'm in the camp of people who use
begin end when the side effect is important and braces when the
return value is important.

I had no idea that there was such a camp. I like that.

Can I come hang out in your camp? I'll bring my own sleeping bag and
marshmallows.

In this case you're welcome. I know I read this in two independent
blog entries, but I can't find them now. So I imagine i do not really
own this camping site :wink:

If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...
:wink:

Kind regards

    robert

<space>

</space>

···

On 12/05/05, Gavin Kistner <gavin@refinery.com> wrote:

On May 12, 2005, at 1:48 AM, Brian Schröder wrote:

On 12/05/05, Phrogz <gavin@refinery.com> wrote:

We are on the same camp. I'm the one who also uses the ternary
operator but doesn't like how it fits with question-mark methods
(@camp.nil? ? 'nil?' : @camp.empty? ? 'empty?' : '!') because it
sounds too intriguing.

Michel.

···

On 5/12/05, Robert Klemme <bob.news@gmx.net> wrote:

Brian Schröder wrote:
> On 12/05/05, Gavin Kistner <gavin@refinery.com> wrote:
>> On May 12, 2005, at 1:48 AM, Brian Schröder wrote:
>>> On 12/05/05, Phrogz <gavin@refinery.com> wrote:
>>>> I tend to use {
>>>> and } for blocks instead of begin/end in my own code because IMHO
>>>> it visually groups it better, but I used begin/end here since that
>>>> seems to be the emerging multi-line choice of the community.)
>>>
>>> I just wanted to throw in that I'm in the camp of people who use
>>> begin end when the side effect is important and braces when the
>>> return value is important.
>>
>> I had no idea that there was such a camp. I like that.
>>
>> Can I come hang out in your camp? I'll bring my own sleeping bag and
>> marshmallows.
>>
>
> In this case you're welcome. I know I read this in two independent
> blog entries, but I can't find them now. So I imagine i do not really
> own this camping site :wink:

If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...
:wink:

I like the ternary folks, we hang out quite a bit.

But you single-line/multi-line folks are...well...odd.

I've never seen so many people eat marshmallows as well as pork and beans at the same time.

···

On May 12, 2005, at 7:35 AM, Robert Klemme wrote:

If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...

Robert Klemme said:

If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...
:wink:

I use to pitch my tent in the one line => braces camp. But every time my
one liner tent grew to more than one line, they made me repitch my tent
using begin/end tent stakes. That's when I moved to the return value =>
brace camp.

BTW, I do regularly hike up to the ternary operator camp as well, so I'll
see you there.

···

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Hi --

If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...

I like the ternary folks, we hang out quite a bit.

But you single-line/multi-line folks are...well...odd.

From 1.8.2 lib:

$ grep " do " `find . -name "*.rb"` | wc -l
    1104
$ grep " do " `find . -name "*.rb"` | grep "end" | wc -l
      37 $ grep "{ *|" `find . -name "*.rb"` | wc -l
    1047
$ grep "{ *|" `find . -name "*.rb"` | grep "}" | wc -l
     647

I know, it's not 100% reliable... but it suggests that, at least
roughly, 3% of 'do' blocks end on the same line, while 62% of {}
blocks end on the same line. So this "odd" behavior is actually
pretty canonical :slight_smile:

David

···

On Thu, 12 May 2005, Gavin Kistner wrote:

On May 12, 2005, at 7:35 AM, Robert Klemme wrote:

--
David A. Black
dblack@wobblini.net

I know no one asked, but I'll share this because I think it's cool. :slight_smile:

I wrote a macro in my editor that turns:

... { |...| ... } ...

into:

... do |...|
     ... (places cursor here)
end ...

I use it all the time and love it. Just a thought.

James Edward Gray II

···

On May 12, 2005, at 9:32 AM, Jim Weirich wrote:

I use to pitch my tent in the one line => braces camp. But every time my
one liner tent grew to more than one line, they made me repitch my tent
using begin/end tent stakes.

* Jim Weirich <jim@weirichhouse.org> [2005-05-12 23:32:52 +0900]:

I use to pitch my tent in the one line => braces camp. But every time my
one liner tent grew to more than one line, they made me repitch my tent
using begin/end tent stakes. That's when I moved to the return value =>
brace camp.

I came from the C camp, where everything looked like {}.
Since my editor supported matching these curly things,
I (usually) pitch camp at { || ... }.
Not sure I know where this return-value camp is at?
Anyone care to provide me a map?

PS: The 'do || ... end' camp keeps telling me that my editor
will match 'do/end' pairs, but I always find the tents
are broken at that camp.

BTW, I do regularly hike up to the ternary operator camp as well, so I'll
see you there.

I too like this camp since it is a short hike, but since I
don't like strenuous activitiy, I never nest them.

···

--
Jim Freeze
Ruby: I can explain it to ya but I can't understand it fer ya.

it's a bit OT - but that's the single reason i made my traits lib define both
a reader method AND query method for each trait (by default). eg. you can do
this

   class C
     has :a => 42
   end
   c = C::new

then either

   if c.a?
     p 'a'
   else
     p 'not a'
   end

OR

   p(c.a ? 'a' : 'not a')

for any/all traits because i too find the 'var? ?...' construct just a wee bit
interrogative - yet prefer to use the ternary op if at all possible.

cheers.

-a

···

On Thu, 12 May 2005, Michel Martens wrote:

On 5/12/05, Robert Klemme <bob.news@gmx.net> wrote:

Brian Schr=F6der wrote:

On 12/05/05, Gavin Kistner <gavin@refinery.com> wrote:

On May 12, 2005, at 1:48 AM, Brian Schr=F6der wrote:

On 12/05/05, Phrogz <gavin@refinery.com> wrote:

I tend to use {
and } for blocks instead of begin/end in my own code because IMHO
it visually groups it better, but I used begin/end here since that
seems to be the emerging multi-line choice of the community.)

I just wanted to throw in that I'm in the camp of people who use
begin end when the side effect is important and braces when the
return value is important.

I had no idea that there was such a camp. I like that.

Can I come hang out in your camp? I'll bring my own sleeping bag and
marshmallows.

In this case you're welcome. I know I read this in two independent
blog entries, but I can't find them now. So I imagine i do not really
own this camping site :wink:

=20
If you got thrown out you can come over to my camp ("it's on one line ?
use braces : use 'do ... end'") - we have plenty of space over here. As
you can see I also frequently visit the ternary operator camp...
:wink:

We are on the same camp. I'm the one who also uses the ternary
operator but doesn't like how it fits with question-mark methods
(@camp.nil? ? 'nil?' : @camp.empty? ? 'empty?' : '!') because it
sounds too intriguing.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
renunciation is not getting rid of the things of this world, but accepting
that they pass away. --aitken roshi

===============================================================================

So, am I the only one that sees the question "do I use braces or do/end" as
being a problem with Ruby?

One of the strengths Ruby has over Perl is that there may be more than one
way to do things, but generally it feels like there's one way that'e
easier. The easiest way turns often turns out to be the right way. As a
result, most people's code ends up looking pretty similar.

This duality of braces and do/end is a glaring example of a case where this
isn't true. There's no inherent reason why someone should choose do/end
or braces. It's all personal preference. As a result, people make up
their own reasons for using one, or the other, or both but under different
circumstances.

For a while I always used braces because blocks really are different. You
only really notice this difference when you're trying to run code in a
debugger. When you do that, stepping to the "next line" takes you all
over the place until eventually something calls 'yield' and you finally
step into the block. Because of that, I used braces all the time to note
that blocks were special.

Now I sorta follow the convention that one-liners are braces, the rest are
do-end, but I don't like it.

The problem is that { a >= b } and { a => b } sure look pretty similar but
one's a block the other is a hash.

I know it's way too late for the Ruby 1.X series, but I'd like to see a
change for Ruby 2 that reserved braces for hashes and blocks had to have
do/end.

Thoughts?

Ben

···

On Thursday 12 May 2005 10:32, Jim Weirich wrote:

I use to pitch my tent in the one line => braces camp. But every time my
one liner tent grew to more than one line, they made me repitch my tent
using begin/end tent stakes. That's when I moved to the return value =>
brace camp.

BTW, I do regularly hike up to the ternary operator camp as well, so I'll
see you there.

Yup...I see that the standard code and the community have somewhat decided upon this convention. When I write code that I'll be releasing into the wild, I've recently been trying it out (just like I change my tabs to 2-spaces before publishing). But I hate it :slight_smile:

···

On May 12, 2005, at 8:24 AM, David A. Black wrote:

I know, it's not 100% reliable... but it suggests that, at least
roughly, 3% of 'do' blocks end on the same line, while 62% of {}
blocks end on the same line. So this "odd" behavior is actually
pretty canonical :slight_smile:

David A. Black said:

I know, it's not 100% reliable... but it suggests that, at least
roughly, 3% of 'do' blocks end on the same line, while 62% of {}
blocks end on the same line. So this "odd" behavior is actually
pretty canonical :slight_smile:

Hmmm ... More statistics, same code base, same disclaimers.

dev05$ find . -name '*.rb' | xargs egrep '(each|loop) *do' | wc -l
    1112
dev05$ find . -name '*.rb' | xargs egrep '(each|loop) *{' | wc -l
     878
dev05$ find . -name '*.rb' | xargs egrep
'(collect|map|find|find_all|select|((inject|grep) *\(.*\))) *do' | wc -l
      68
dev05$ find . -name '*.rb' | xargs egrep
'(collect|map|find|find_all|select|((inject|grep) *\(.*\))) *{' | wc -l
     657

So, nearly 55% of methods that ignore the return value of the block use
do/end.

Over 90% of the methods that use the block's value use {}.

So you can use either style and claim to be main-stream.

···

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

* Jim Freeze <jim@freeze.org> [2005-05-13 00:33:15 +0900]:

Not sure I know where this return-value camp is at?
Anyone care to provide me a map?

Never mind. David Black posted a map for me.

···

--
Jim Freeze
Ruby: I can explain it to ya but I can't understand it fer ya.

* Jim Weirich <jim@weirichhouse.org> [2005-05-12 23:32:52 +0900]:

> I use to pitch my tent in the one line => braces camp. But every time my
> one liner tent grew to more than one line, they made me repitch my tent
> using begin/end tent stakes. That's when I moved to the return value =>
> brace camp.
>

I came from the C camp, where everything looked like {}.
Since my editor supported matching these curly things,
I (usually) pitch camp at { || ... }.
Not sure I know where this return-value camp is at?
Anyone care to provide me a map?

A simple example:

print "100! = "
puts (1..100).inject(1) { |r,v|
  r*v
}

(1..100).inject(1) do |r,v|
  puts "#{v}! = #{r*=v}"
  r
end

regards,

Brian

···

On 12/05/05, Jim Freeze <jim@freeze.org> wrote:

PS: The 'do || ... end' camp keeps telling me that my editor
will match 'do/end' pairs, but I always find the tents
are broken at that camp.

> BTW, I do regularly hike up to the ternary operator camp as well, so I'll
> see you there.

I too like this camp since it is a short hike, but since I
don't like strenuous activitiy, I never nest them.

--
Jim Freeze
Ruby: I can explain it to ya but I can't understand it fer ya.

--
http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

Hi --

···

On Fri, 13 May 2005, Ben Giddings wrote:

I know it's way too late for the Ruby 1.X series, but I'd like to see a
change for Ruby 2 that reserved braces for hashes and blocks had to have
do/end.

Thoughts?

You'll have to fight it out with the ones who wanted braces for block
literals and hashes to be something else :slight_smile:

David

--
David A. Black
dblack@wobblini.net