1

So, I have a ruby loop, how do I print a message every 50 iteration in it, like this:

loop do
  do something
  break if something happend
  puts "Message at every 50 iteration"
end
mjgpy3
  • 8,597
  • 5
  • 30
  • 51
  • 1
    It would be helpful to know what's the condition that breaks the loop. – Shoe Apr 25 '13 at 02:11
  • It'd also help to know what you're doing in the loop. It's quite possible there are other ways to do this - you may get better answers if you state the **aim** *not* the _implementation_. – ian Apr 25 '13 at 02:26

3 Answers3

6

Keep a counting variable, and do something every time it becomes divisible by 50.

i = 0;

loop do
  i += 1

  if i % 50 == 0
    puts "This prints every 50 iterations"
  end
end
user229044
  • 232,980
  • 40
  • 330
  • 338
  • 1
    Because it wasn't explained for the OP: `i % 50 == 0` works basically as if `i` is divided by `50`, only it returns the remainder, so we can find even boundaries by looking for `0`, or if you wanted the boundary + some number you could look for that number. – the Tin Man Apr 25 '13 at 02:06
  • 3
    And if this is a daemon-like process, I would also reset i inside the `if` statement just to be sure I don't overflow the maximum integer value possible. (I don't remember if there is one in Ruby or not, but it's still good to be paranoid.) – Ian Stapleton Cordasco Apr 25 '13 at 03:16
  • @sigmavirus24: The maximum value of an integer in Ruby is only limited by the amount of memory it takes to represent that integer. So, on a typical server machine with, say, 16 GiByte of RAM, the maximum integer value is roughly 256**(16*1024*1024*1024), i.e. 2**(2**42), which is 2**4398046511104 or roughly 10**1319413953331, i.e. a 10 with 1.3 billion zeroes. – Jörg W Mittag Apr 25 '13 at 08:32
4

Donald Knuth (perhaps not in Ruby) would use an index that counts down instead of one that counts up. That makes the check easier. It also avoids the problem of integer overflow as sigmavirus24 points out.

i = 50
loop do
  # do something
  break if something happend # (as in original)
  i -= 1
  next unless i.zero?
  i = 50
  puts "Message at every 50 iteration"
end
Shoe
  • 74,840
  • 36
  • 166
  • 272
sawa
  • 165,429
  • 45
  • 277
  • 381
  • Could you please explain why count-down is better? I'm interested. – Jun Zhou Apr 25 '13 at 05:38
  • Divide `i` by `50` and see if it is zero. Do this a thousand times while `i` changes. Next see if `i` is zero a thousand times while it changes. Which would you volunteer to do? – sawa Apr 25 '13 at 05:40
  • Well, that makes a good point. Besides, I saw you mentioned Donald Knuth, is there any source? Thank you. – Jun Zhou Apr 25 '13 at 05:46
  • Donald Knuth *The TeXbook*. – sawa Apr 25 '13 at 05:49
  • That code is a *mess* for a problem that basically doesn't exists: Fixnums are automagically converted to Bignums when they overflow (the size of which dynamically change to fit *technically* any number). – Shoe Apr 25 '13 at 13:21
  • @Jueecy.new I did not write Fixnum. I wrote more vaguely integers. Bignum, or whatever, will eventually reach the limit as long as it is running on a physically bounded computer. – sawa Apr 25 '13 at 13:29
  • Knuth is highly respected, however his intent was teaching the logic of coding and making it reasonably readable and maintainable. His examples can be translated into assembler, C or Ruby, because it's all in byte/bite-size pieces, however it won't necessarily result in the most optimal code for a language. He put the training wheels on the bicycle and taught us to ride, but I think he expected us to learn and eventually take them off again. We have other constructs and ways of accomplishing the same things in a more Ruby-like manner. – the Tin Man Apr 25 '13 at 13:38
0

Considering your condition to be c I think the cleanest way is to use a while loop (or unless depending on the condition):

while c do
    i = (i) ? i + 1 : 1
    puts "This prints every 50 iterations" if (i % 50 == 0)
end
Shoe
  • 74,840
  • 36
  • 166
  • 272
  • This isn't written like Ruby should be written, it's written like C or Perl. – the Tin Man Apr 25 '13 at 05:38
  • @theTinMan, just because it uses `while` instead of `loop`? – Shoe Apr 25 '13 at 13:06
  • `while` is seldom used, `loop do` is [recommended](http://stackoverflow.com/a/10713963/128421). Initializing `i` with a ternary is borderline but it's the use of a single-line `if` with semi-colons that is the most un-Ruby-like. `puts ... if (i % 50 == 0)` is idiomatic. – the Tin Man Apr 25 '13 at 13:27
  • @theTinMan, please re read your link. It says that `loop` is preferred over `begin - end while -` not over `while do`. On the semicolon `if` I totally agree and thank you to have made me notice it. – Shoe Apr 25 '13 at 13:33
  • `while` is also seldom used in Ruby; Notice how often it's used on this page. And, if you read http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745, pointed to in that answer, Matz avoids both `do`/`while` loops and `while` loops suggesting the use of `loop` instead. – the Tin Man Apr 25 '13 at 13:48