8.times versus for i in 1..8
I've recently came across a code excerpt that piqued my interest.
# Taken from Ace Equip Engine, Yanfly Engine Ace# All credits and copyrights where they due.8.times {|i| draw_item(0, line_height * i, i) }
The syntax above essentially repeats the instructions in the block given after the times method call as much as 8 times. If we define this code using a for loop, an equivalent would be:
for i in 0..8 do draw_item(0, line_height * i, i)end
Then a question arose on my mind. Which would be better and why?
Let's consider the pros and cons of both code structures.
First one is the times function. This function actually calls for an iterator block, requiring evaluation, as it defines a yield clause in its definition. It basically repeats the instructions in the iterator block, yielding a local variable to signal how many times the iteration had performed, as much as n times, where n is the said number. 8.times would mean 8 times.
A consideration would be if the number is not a number literal, but is a variable that contains a numeric value. Fine, we can use to_i to convert non-integer to integer values, but what if the variable ends up being a negative number?
exa = 0exa -= rand <= 0.5 ? 1 : -1# ...# at this point, exa would contain either positive or negative number, and we want to perform a loop# of instruction for exa times.exa.to_i.times do |ex| puts ex + "\n"end
The RPG Maker VX Ace help files mention that if the instance variable that calls the times function is a negative number, it does nothing. It doesn't matter if we mean to check for negative variables, since we can simply just exa.abs.to_i.times do |ex| things out, but if we meant to do a loop (say, if exa is 2, then we want a loop 2 times, as do if exa is -2, and using abs function is tedious in your opinion), in such cases, the for loop is handy.
exa = 0exa -= rand <= 0.5 ? 1 : -1# blablablafor ex in 0..exa do puts ex + "\n"end
This way, whether exa is positive or negative, the loop will still perform its job.
The downside of a for loop is that while iterator expressions introduces a new block scope for local variables (and thus, we can perform wider range of actions inside the block scope), for loops doesn't introduce such scopes, and so, for has no effects on local variables.
Basically, we would say that the following two loops will output the same.
8.times do { |x| puts x }for x in 0..8 do puts x end
So, we can conclude that both of them are equivalent in terms of performance. If we want to perform operations that modify the local variable passed to the loop, then the times and iterator block expression would come handy. Otherwise, the for loop might come in handy as well. The usage of both of them mutually is a choice of each own programmer.
-
1



13 Comments
Recommended Comments