Why does Ruby every iterator go first in execution?

I came across a strange thing doing simple tasks in Ruby. I just want to iterate over the alphabet with each method, but the iteration goes first in execution:

alfawit = ("a".."z") puts "That an alphabet: \n\n #{ alfawit.each { |litera| puts litera } } " 

and this code leads to the following: (abbreviated)

 a b c ⋮ x y z That an alphabet: a..z 

Any ideas why this works this way or what supposedly I did wrong?

Thanks in advance.

+5
source share
2 answers

Since your call to each interpolated into a string literal that runs before a fixed string. In addition, each returns Enumerable , in fact you print even that. Try this one

 alfawit = ("a".."z") puts "That an alphabet: \n\n" alfawit.each { |litera| puts litera } 

or

 puts "That an alphabet: \n\n" ("a".."z").each { |litera| puts litera } 

you can use interpolation if you want, but in this way

 alfawit = ("a".."z") puts "That an alphabet: \n\n#{alfawit.to_a.join("\n")}" 
+5
source

You can easily see what happens if you extract part of the interpolation into a variable:

 alfawit = ("a".."z") foo = alfawit.each { |litera| puts litera } puts "That an alphabet: \n\n #{ foo } " 

The second line causes a problem: each calls a block for each element of the range, and then returns the receiver, so that foo becomes alfawit .

Here is another way to get the desired result:

 alfawit = "a".."z" puts "That an alphabet:", alfawit.to_a 

puts displays each argument on a new line, but for array arguments, it displays each element on a new line. Result:

 That an alphabet: a b c ⋮ x y z 

Similarly, you can turn a range into an argument list with * :

 alfawit = "a".."z" puts "That an alphabet:", *alfawit 

This is equivalent to:

 puts "That an alphabet:", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 
+3
source

Source: https://habr.com/ru/post/1264503/


All Articles