0

Ruby, which is normally very forgiving, is giving me an error on a while loop; I can't see why.

def foo(vals)
  n = vals.length
  key = n-1
  newkey = n-1

  while ((key > 0) && (vals[key] <= vals[key-1])) key--

  key
end

The error:

prog.rb:37: syntax error, unexpected tIDENTIFIER, expecting keyword_do_cond or ';' or '\n'
    while ((key > 0) && (vals[key] <= vals[key-1])) key--
                                                       ^

Any ideas?

James Gilles
  • 674
  • 6
  • 12
  • possible duplicate of [ruby incrementing integer](http://stackoverflow.com/questions/7993915/ruby-incrementing-integer) – Andrew Grimm Jan 10 '12 at 00:41

3 Answers3

3

Ruby has no pre/post increment/decrement operator. We use x -= 1 and paste it before while if you want one liner.

def foo(vals)
  n = vals.length
  key = n-1
  newkey = n-1

  key -= 1 while ((key > 0) && (vals[key] <= vals[key-1]))
  key
end
Igor Kapkov
  • 3,779
  • 2
  • 19
  • 19
2

Ruby may be sometimes forgiving, but not about non-existing operators: key-- -> key -= 1

You are using Ruby as it were a low level language (as C), a more idiomatic (and functional) approach:

def foo(vals)
  (vals.size - 1).downto(1).detect { |idx| vals[idx] > vals[idx-1] } || 0
end
tokland
  • 66,169
  • 13
  • 144
  • 170
1

Ruby doesn't have the -- or ++ unary operators, nor the while syntax you're trying to use. Try this instead:

while key > 0 && vals[key] <= vals[key - 1] do key -= 1 end

As @IgorKapkov suggests you can also turn it around, which is more Rubyish:

key -= 1 while key > 0 vals[key] <= vals[key - 1]
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
  • "_But beware, this does have different semantics since the part before while will be executed before the first test of the conditional that follows._" It's not true. For example: `x = 1 ; puts "first" while x < 1 ; while x < 1 do puts "second" end` it's the same. – Igor Kapkov Jan 09 '12 at 22:59