Project

General

Profile

Feature #21615

Updated by matheusrich (Matheus Richard) 2 days ago

## Motivation 

 In Ruby code, it's common to accept arrays and hashes and treat them uniformly as collections of values. `Hash` exposes `#values`, but `Array` does not, which pushes developers toward `is_a?`/`respond_to?` branching. 

 Following the **Principle of Least Surprise**, users may reasonably expect `Array#values` to exist because: 

 * Both `Array` **and** `Hash` already implement `#values_at`. 
 * `Hash` implements `#values` but `Array` does not. 

 ### Example 

 Today: 

 ```ruby 
 def normalize_records(input) 
   items = input.respond_to?(:values) ? input.values : input 

   items.each do |item| 
     do_stuff_with_item(item) 
   end 
 end 
 ``` 

 With `Array#values`: 

 ```ruby 
 def normalize_records(input) 
   input.values.each do |item| 
     do_stuff_with_item(item) 
   end 
 end 
 ``` 

 ## Proposal 

 Add `Array#values`, returning a copy of the elements of `self`. Implementation could simply alias to `itself`: 

 ```ruby 
 class Array 
   alias_method :values, :itself 
 end 
 ``` 

 This yields a uniform interface for `Array` and `Hash` values without type checks. 

 ### Alternatives considered 

 * `Enumerable#values`: defaulting to `to_a`, but I found it too broad of a change. 
 * `Array#each_value`: redundant as `Array#each` already covers iteration. 


 Patch: https://github.com/ruby/ruby/pull/14641

Back