2008-09-30 39 views
23

Trong Ruby:là gì "cho" trong Ruby

for i in A do 
    # some code 
end 

là giống như:

A.each do |i| 
    # some code 
end 

for không phải là một phương pháp kernel:

  • gì chính xác là "for "trong ruby ​​
  • Có cách nào để sử dụng các từ khóa khác để thực hiện những việc tương tự không ?

Cái gì như:

total = sum i in I {x[i]} 

ánh xạ tới:

total = I.sum {|i] x[i]} 

Trả lời

45

Đó gần như là đường cú pháp. Một khác biệt là, trong khi for sẽ sử dụng phạm vi mã xung quanh nó, each tạo phạm vi riêng trong khối của nó. Hãy so sánh như sau:

for i in (1..3) 
    x = i 
end 
p x # => 3 

so

(1..3).each do |i| 
    x = i 
end 
p x # => undefined local variable or method `x' for main:Object 
+0

Wow, rất tinh tế, nhưng sẽ trở nên tiện dụng khi tôi chạy vào một cái gì đó như thế này. Cảm ơn! – sivabudh

+0

Trên thực tế ví dụ thứ hai của bạn ném 'NameError: biến không xác định cục bộ hoặc phương thức 'i' cho chính: Object'. Đó là bởi vì bạn đang thiếu 'do'. –

+0

@JakubHampl Tôi đã sửa nó. Cảm ơn! –

14

for là đường chỉ cú pháp cho phương pháp each. Điều này có thể được nhìn thấy bằng cách chạy mã này:

for i in 1 do 
end 

Điều này dẫn đến các lỗi:

NoMethodError: undefined method `each' for 1:Fixnum 
+3

-1 vì có sự khác biệt giữa hai, và họ không phải lúc nào tương đương. – user2398029

9

Đối với chỉ là cú pháp đường.

Từ the pickaxe:

For ... In

Earlier we said that the only built-in Ruby looping primitives were while and until. What's this ``for'' thing, then? Well, for is almost a lump of syntactic sugar. When you write

for aSong in songList 
    aSong.play 
end 

Ruby translates it into something like:

songList.each do |aSong| 
    aSong.play 
end 

The only difference between the for loop and the each form is the scope of local variables that are defined in the body. This is discussed on page 87.

You can use for to iterate over any object that responds to the method each, such as an Array or a Range.

for i in ['fee', 'fi', 'fo', 'fum'] 
    print i, " " 
end 
for i in 1..3 
    print i, " " 
end 
for i in File.open("ordinal").find_all { |l| l =~ /d$/} 
    print i.chomp, " " 
end 

produces:

fee fi fo fum 1 2 3 second third 

As long as your class defines a sensible each method, you can use a for loop to traverse it.

class Periods 
    def each 
    yield "Classical" 
    yield "Jazz" 
    yield "Rock" 
    end 
end 


periods = Periods.new 
for genre in periods 
    print genre, " " 
end 

produces:

Classical Jazz Rock 

Ruby không có các từ khóa khác cho comprehensions danh sách (như ví dụ tổng bạn đã thực hiện ở trên). for không phải là từ khóa phổ biến khủng khiếp và cú pháp phương pháp (arr.each {}) thường được ưu tiên.