Normal For Loop

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.

Also, is there anything like i++ or do I always have to do i=i+1 ?

···

--
Posted via http://www.ruby-forum.com/.

Cory Cory wrote:

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.
  
We would be very interested to see a loop in C that cannot be rewritten in Ruby. Care to give us an example?

Also, is there anything like i++ or do I always have to do i=i+1 ?
  

You can use i += 1.

There is 5.times {|i| } if the count is known at cycle start.
Then you have array.each {}, and the whole bunch from Enumerable
(each_with_index, select, find, map, inject, ...)

···

On Mon, Mar 3, 2008 at 3:10 PM, Cory Cory <cg821105@ohio.edu> wrote:

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.

["foo", "bar", "baz"].each_with_index {|elem, i|
  puts "#{elem} #{i}"
}

    Kristian

···

On Mon, 3 Mar 2008 23:10:09 +0900, Cory Cory <cg821105@ohio.edu> wrote:

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

for n in 1..10
    puts n
end

It seems more common in ruby to do things like

1.upto(10) {|n| puts n}

or

(1..10).each {|n| puts n}

If you mean that you want your condition and your increment to depend
on things that you won't know about until after the loop has been
running for a while, then yeah, you might have to use a while loop.
This doesn't seem to come up much, though. Perhaps you could post a
specific example.

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.

With a little creativity, not so many, in my experience.

Also, is there anything like i++ or do I always have to do i=i+1 ?

i=i+1 is the way to do it. There is some rationale for this, but I
don't remember what it is.

JM

···

On Mar 3, 9:10 am, Cory Cory <cg821...@ohio.edu> wrote:

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

Simply put, no, Ruby has nothing that works quite like the C-style for loop.

I know I can do that with a while loop, but I enjoy the compactness of
the above statement.

Usually, there is a simpler compact idiom using the iterator methods in the
Enumerable module or specific container classes like Array if you need
something more compact than a while loop.

There are many times where Ruby's for-each loops
just don't do the trick.

The main looping tehcnique in Ruby is using iterator methods. You
could make something like the C-style for loop using them, with the caveat
that all the loop parameters have to be specified as proc objects. It would
be something like (this is code from the top of my head):

module Kernel
  def cfor (init, condition, increment)
    init.call
    while condition.call
      yield
      increment.call
    end
  end
end

But, even if proc objects didn't make calling this a little ugly,
you really don't need it: there is generally a better more specific
way of doing things in Ruby.

For instance, in the example you give later in the thread:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
  minValue = (5000 - a[i]).abs
}

You seem to want to find the index of the first item in the array
that equals 5000 (which is what the value of i is when you bail
out) or the absolute value of 5000 minus the last item value in
the area (what minValue is if you fail to bail out).

so:

a = some_array
i = a.index(5000) || a.length
minValue = (i<a.length) ? 0 : (5000-a.last).abs

You can probably do something more elegant depending on
what you are doing with the results.

Also, is there anything like i++ or do I always have to do i=i+1 ?

You can do i+=1, i=i.succ, or i=i.next, if you prefer, but Ruby doesn't have
the increment or decrement operators of the C family.

···

On Mon, Mar 3, 2008 at 6:10 AM, Cory Cory <cg821105@ohio.edu> wrote:

This piece of code was done as an exercise from Learn Ruby The Hard
Way.
I think this is more along the line of the type of for loop you are
looking for. The function's purpose may seem trivial but let me know if
this helped anyone.

def number_increaser2(max_number, increment)
  # i = 0
  numbers = []

  for i in (0..max_number).step(increment)
    if max_number > 0
        numbers.push(i)
        puts i
        puts "Numbers now: #{numbers.join(" ")}"
            else
        puts "Max_number was too little!!\n"
        return []
          end
  end

  return numbers
end

···

--
Posted via http://www.ruby-forum.com/.

Thank you.

OK, I deduce from this

a. There are any number of ways of generating a loop.
b. It would be possible for a Ruby programmer to write new ones.

Is this correct?

···

--
Posted via http://www.ruby-forum.com/.

Yes, and you can write some very creative loops if you want, as abstract
or as precise as you like. There are some great options with
multiple-variable loops. Using blocks and yield makes for some amazing
loop options in Ruby.

···

--
Posted via http://www.ruby-forum.com/.

Hmmm. The basic principle of (just about) all programming is, as we all
know, KISS. Because the more complicated it is

a. the more likely there are to be errors
b. the harder it becomes to maintain.

I fear (in absence of knowledge, I'm just starting don't forget) that
'amazing loop options' makes the writing overly clever,
incomprehensible code too easy. I'd love to be wrong...?

···

--
Posted via http://www.ruby-forum.com/.

I was referring to situational things like yielding multiple objects to
a loop as an array, adding an index, using yield rather than having a
staticly defined method...

···

--
Posted via http://www.ruby-forum.com/.

My apologies, I was not making a personal remark. I am hopelessly
underqualified to discuss any basic, never mind advanced, features of
Ruby.

My question was general, perhaps I'll try again -- is it easy for a bad
programmer to write overly complicated code?

···

--
Posted via http://www.ruby-forum.com/.

Jano Svitok wrote:

···

On Mon, Mar 3, 2008 at 3:10 PM, Cory Cory <cg821105@ohio.edu> wrote:

I'm new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby's for-each loops
just don't do the trick.

There is 5.times {|i| } if the count is known at cycle start.
Then you have array.each {}, and the whole bunch from Enumerable
(each_with_index, select, find, map, inject, ...)

Not to mention Numeric#step:

1.step(10, 2) { |i| print i, " " }

And Integer#upto:

5.upto(10) { |i| print i, " " }
--
Posted via http://www.ruby-forum.com/\.

I understand that all of these for-each style loops are available, but I
don't want to always go through the entire loop, sometimes I want to
stop at some earlier condition.

I tried to do this the other night, but right now I can't find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
   minValue = (5000 - a[i]).abs
}

This isn't the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

···

--
Posted via http://www.ruby-forum.com/.

IIRC, the rationale is that variables in ruby are just references to
objects, so you cannot call methods
on variables themselves. You call methods on objects they reference.
That means a call (except assignment)
cannot change the object a variable points to.

i.e. i = 3 that means, variable i points to/references object 3 of class Fixnum.
if there was a call ++, (i++) that would mean the same as 3++. 3++
call can be written so that it returns 4
(actually it's called 3.succ), but there's no way to assign 4 back to
i. It would still point to 3. And because Fixnums are
singletons (there's only one "3" object) they are read only, so
there's no 3.succ!

···

On Mon, Mar 3, 2008 at 3:29 PM, jwmerrill@gmail.com <jwmerrill@gmail.com> wrote:

i=i+1 is the way to do it. There is some rationale for this, but I
don't remember what it is.

I tried to do this the other night, but right now I can't find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
   minValue = (5000 - a[i]).abs

}

What does this example do exactly? It seems to run until it finds a
value in a that is equal to 5000, and then stop without reporting
anything.

a.detect {|n| 5000 == n}

or

a.any? {|n| 5000 == n}

See, this is actually more concise and readable, I think.

This isn't the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

The point is not that no examples exist, but that they realistically
don't come up very much. Get familiar with the methods in Enumerable,
Array, and Numeric. Each time you want to write a for loop, try and
use one of those instead, and if you get stuck, ask for advice.
You're solution will almost always be more readable, and maybe 1 time
in 100 you'll need to use a while loop.

JM

···

On Mar 3, 9:37 am, Cory Cory <cg821...@ohio.edu> wrote:

Cory Cory ha scritto:

I understand that all of these for-each style loops are available, but I
don't want to always go through the entire loop, sometimes I want to
stop at some earlier condition.

I tried to do this the other night, but right now I can't find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
   minValue = (5000 - a[i]).abs
}

This isn't the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

In this case you can use "break" construct (which I, personally,
love). For example,

minValue = 999999
a.each do |x|
  minValue = (5000-x).abs
  break if minValue==0
end

(I did not actually try it, but it should work)

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

In this case I'm afraid that you must resort to a while... (BTW, I
always considered
C-style "for" as a "while" in disguise... :wink:

···

--
Posted via http://www.ruby-forum.com/\.

Cory Cory wrote:
[for-loops instead of Array#each and friends]

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
   minValue = (5000 - a[i]).abs
}

Break is your friend;
Some solutions for this example:

# No. 1
# (assuming that you are going to process the element, in this case,
# printing it to STDOUT and adding a newline):
a = [100, 200, 3000, 5000, 80000] # Arbitrary Array initialisation,
                                  # will be needed for all examples.
a.each {|i|
  break if (5000-i).abs == 0
  puts i
}
100
200
3000
    ==>nil

# No. 2
# returning an array with elements *not* meeting the condition
a.reject { |i| (5000-i).abs == 0 } # Can also be used as 'select'
                                   # with inverted condition
    ==>[100, 200, 3000, 80000]

# No. 3
# returning an array without elements > 5000
a.select { |i| i < 5000 }
    ==>[100, 200, 3000]

# No. 4
# contrived example, using #map and #compact
# Warning: Don't try this at home
a.map { |i| i < 5000 ? i : nil }.compact
    ==>[100, 200, 3000]

# No. 5
# contrived example again, this time using 'size' and artificial
# 'index'; using exact condition, so 'unless' is needed instead of
# 'if'. Using puts for 'debug' messages, or instead of processing
# values. Less readable.
a.size.times { |i|
  break unless (5000 - a[i]).abs != 0
  puts a[i]
}
100
200
3000
    ==>nil

This isn't the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

That's what 'break' is for.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

For Array manipulation, selection etc, refer to 'ri Array' - I can't
see how 'C-style for loops' would help there either.

t.

···

--
Anton Bangratz - Key ID 363474D1 - http://tony.twincode.net/
fortune(6):
Signs of crime: screaming or cries for help.
    -- The Brown University Security Crime Prevention Pamphlet

I tried to do this the other night, but right now I can't find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
   minValue = (5000 - a[i]).abs
}

This isn't the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

I have a "good" example. In my case I want to iterate a collection,
skipping a variable number of elements based on a given element.
In this case, the C for construct (counter_init, cycle_condition,) would
be useful because I wouldn't have to initialize the counter variable
outside of the scope, and I can increment the counter inside the loop.

The code is something like this:

for ( i = 0; i < elements.size; ) do
  if elements[ i ].is_a?( OneType )
    do_operation( elements[ i ] );
    i += 1;
  elsif elements[ i ].is_a?( AnotherType )
    sub_elements =
    begin
      sub_elements << elements[ i
      i += 1;
    end while elements[ i ].is_a?( AnotherType )
    do_another_operation( sub_elements )
  else
    ...
  end
end

This example doesn't pretend to be clever/correct/well constructed, but
is a real-world case where this kind of loop would be useful.

···

--
Posted via http://www.ruby-forum.com/\.

Alle Monday 03 March 2008, jwmerrill@gmail.com ha scritto:

···

On Mar 3, 9:37 am, Cory Cory <cg821...@ohio.edu> wrote:
> I tried to do this the other night, but right now I can't find a good
> example so here it goes:
>
> a = some_array
> minValue = 999999
> for(i=0; i<a.length && minValue!=0; i+=1) {
> minValue = (5000 - a[i]).abs
>
> }

What does this example do exactly? It seems to run until it finds a
value in a that is equal to 5000, and then stop without reporting
anything.

a.detect {|n| 5000 == n}

or

a.any? {|n| 5000 == n}

See, this is actually more concise and readable, I think.

> This isn't the best example. However, there are many times like the
> loop above where I want to go through the whole thing, but if I find
> exactly what I am looking for, I want to bail out early instead of
> wasting that processing time.
>
> Also, I sometimes may want to not actually iterate straight through, but
> browse through the array in some more complex order.

The point is not that no examples exist, but that they realistically
don't come up very much. Get familiar with the methods in Enumerable,
Array, and Numeric. Each time you want to write a for loop, try and
use one of those instead, and if you get stuck, ask for advice.
You're solution will almost always be more readable, and maybe 1 time
in 100 you'll need to use a while loop.

JM

If you want to exit the loop before all iterations are done, you can use
break.

Stefano