The method of deductions and time by numbers

This code:

puts 1.times { puts 2.times { puts 3.times { puts 4 } } } 

Outputs the following:

 4 4 4 3 4 4 4 3 2 1 

I would expect Ruby to output the return value of the times method, but it seems like it is not. It prints the number to which times is called. What's happening?

+7
ruby
source share
3 answers

I don't get this conclusion either, so resolve it starting with the innermost expression:

 puts 4 # 4 <- this should denote output #=> nil <- this should denote return value 

It prints 4 and returns nil ( puts always returns nil ).

Wrap at 3.times { ... } prints 4 3 times:

 3.times { puts 4 } # 4 # 4 # 4 #=> 3 

But instead of returning nil it returns 3 . This is because times always returns a receiver (i.e. the integer that you call times ).

Now add another puts :

 puts 3.times { puts 4 } # 4 # 4 # 4 # 3 #=> nil 

The same as above, but also prints the result 3.times { ... } , i.e. 3 .

A wrapper in just 2.times { ... } duplicates the output above:

 2.times { puts 3.times { puts 4 } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 #=> 2 

It also returns 2 instead of nil due to 2.times { ... } .

Adding puts means 2 :

 puts 2.times { puts 3.times { puts 4 } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 # 2 #=> nil 

Wrapping this in 1.times { ... } produces the same output, but changes the result from nil to 1 :

 1.times { puts 2.times { puts 3.times { puts 4 } } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 # 2 #=> 1 

Adding the latest puts fingerprints that are 1 :

 puts 1.times { puts 2.times { puts 3.times { puts 4 } } } # 4 # 4 # 4 # 3 # 4 # 4 # 4 # 3 # 2 # 1 #=> nil 
+3
source share

You have a loop (quasi) in a loop inside a loop, so Ruby does exactly what you ask for it. How these loops are evaluated, generally speaking, from the inside.

The return value from times is the number indicated first, so 3.times returns 3 .

With all of this in mind, you can interpret what is happening like this:

 4 # First iteration of 3.times { puts 4 } 4 4 3 # Return value of 3.times displayed 4 # Second iteration of 3.times { puts 4 } 4 4 3 # Return value of 3.times displayed 2 # Return value of 2.times displayed 1 # Return value of 1.times displayed 

Now that I see code like puts 3.times , which is usually a mistake, the same goes for puts array.each ... where someone probably means .map .

+7
source share

I think I expect Ruby to output the return value of the times method, but it seems like it is not. It prints the number to which times is called.

This is the return value of the times method :

times {|i| block } times {|i| block } β†’ self

+2
source share

All Articles