Project

General

Profile

Feature #16818

Updated by sawa (Tsuyoshi Sawada) over 4 years ago

`Range#%` was introduced as an alias of `Range#step` by 14697, but it is counter-intuitive and confusing. 

 Iteration in the following: 

 ```ruby 
 ((5..14) % 3).each{|i| p i} 
 #>> 5 
 #>> 8 
 #>> 11 
 #>> 14 
 ``` 

 is not based on `x % y` in any sense. In fact, actually applying `% 3` to the selected elements returns a unique value `2`, and it is not obvious how this is related to the iteration. 

 ```ruby 
 [5, 8, 11, 14].map{|i| i % 3} 
 # => [2, 2, 2, 2] 
 ``` 

 Rather, the concept seems to be based on `/`. Applying `/ 3` to the relevant elements returns a sequence `1, 2, 3, 4`. 

 ```ruby 
 [5, 8, 11, 14].map{|i| i / 3} 
 # => [1, 2, 3, 4] 
 ``` 

 Hence, `(5..14).step(3)` can be interpreted like this: Iterate over the [equivalence class](https://en.wikipedia.org/wiki/Equivalence_class) (quotient set) of range `5..14` yielded by `/ 3`. 

 Notice that the number of elements in `[5, 8, 11, 14]` is 4, which is `(14 - 5 + 1) / 3.0).ceil`, but is not related to `%`. 

 So I propose that the alias of `Range#step` should be `Range#/`, and `Range#%` should be deprecated as soon as possible before its use accumulates: 

 ```ruby 
 ((5..14) / 3).each{|i| p i} 
 #>> 5 
 #>> 8 
 #>> 11 
 #>> 14 
 ``` 

 --- 

 P.S. 

 And if `Range#%` were to be introduced at all, I would rather expect it to behave like the following: 

 ```ruby 
 ((5..14) % 3).each{|i| p i} 
 #>> 5 
 #>> 6 
 #>> 7 
 ``` 

 which is why I claimed above that the current `Range#%` is confusing.

Back