views:

154

answers:

2

so, i'm trying to learn ruby by doing some project euler questions, and i've run into a couple things i can't explain, and the comma ?operator? is in the middle of both. i haven't been able to find good documentation for this, maybe i'm just not using the google as I should, but good ruby documentation seems a little sparse . . .

1: how do you describe how this is working? the first snippet is the ruby code i don't understand, the second is the code i wrote that does the same thing only after painstakingly tracing the first:

#what is this doing?
cur, nxt = nxt, cur + nxt

#this, apparently, but how to describe the above?
nxt = cur + nxt   
cur = nxt - cur   

2: in the following example, how do you describe what the line with 'step' is doing? from what i can gather, the step command works like (range).step(step_size), but this seems to be doing (starting_point).step(ending_point, step_size). Am i right with this assumption? where do i find good doc of this?

#/usr/share/doc/ruby1.9.1-examples/examples/sieve.rb  
# sieve of Eratosthenes
max = Integer(ARGV.shift || 100)
sieve = []
for i in 2 .. max
  sieve[i] = i
end

for i in 2 .. Math.sqrt(max)
  next unless sieve[i]
  (i*i).step(max, i) do |j|
    sieve[j] = nil
  end
end
puts sieve.compact.join(", ")
+2  A: 
  1. This a parallel assignment. In your example, Ruby first evaluates nxt and cur + nxt. It then assigns the results to cur and nxt respectively.

  2. The step method in the code is actually Numeric#step (ranges are constructed with (n..m)). The step method of Numeric iterates using the number it is called on as a starting point. The arguments are the limit and step size respectively. The code above will therefore invoke the block with i * i and then each successive increment of i until max is reached.

A good starting point for Ruby documentation is the ruby-doc.org site.

Phil Ross
thanks for this answer. you're explanation of my first question made it really clear to me what was happening.
ryan_m
+3  A: 

1: It's called parallel assignment. Ruby cares to create temporal variables and not override your variables with incorrect values. So this example:

cur, nxt = nxt, cur + nxt

is the same as:

tmp = cur + nxt
cur = nxt
nxt = tmp

bur more compact, without place to make stupid mistake and so on.

2: There are 2 step methods in ruby core library. First is for Numeric class (every numbers), so you could write:

5.step(100, 2) {}

and it starts at 5 and takes every second number from it, stops when reaches 100.

Second step in Ruby is for Range:

(5..100).step(2) {}

and it takes range (which has start and end) and iterates through it taking every second element. It is different, because you could pass it not necessarily numeric range and it will take every nth element from it.

Take a look at http://ruby-doc.org/core-1.8.7/index.html

MBO
so, in this case it doesn't matter, but wouldn't 2 separate temp variables be created for the right side of the assignment? e.g: tmp = cur + nxttmp2 = nxtcur = tmp2nxt = tmp?also, wouldn't the right side of comma on the left side of the assignment be assigned first?
ryan_m
@ryan_n Yes, that's right. But if you program in Ruby, you don't have to care about low level details about how it works as long as you don't try to do something unusual.
MBO