From: matz@... Date: 2020-01-16T06:58:27+00:00 Subject: [ruby-core:96894] [Ruby master Feature#16435] Array#to_proc Issue #16435 has been updated by matz (Yukihiro Matsumoto). Status changed from Open to Rejected Rejected. `Array#to_proc` to too generic for queries. It only makes the code more cryptic. Matz. ---------------------------------------- Feature #16435: Array#to_proc https://bugs.ruby-lang.org/issues/16435#change-83908 * Author: zverok (Victor Shepelev) * Status: Rejected * Priority: Normal * Assignee: * Target version: ---------------------------------------- The idea is obvious, but I couldn't find it discussed anywhere on tracker before. Please point me at the previous discussions if any. ```ruby class Array def to_proc proc { |v| v.dig(*self) } end end # Or, alternatively, see about alternatives at the end of proposal: class Array def to_proc proc { |v| v[*self] } end end ``` The implementation seems to provide clean and unambiguous collections indexing in Enumerators: ```ruby # Basic objects data, which could be obtained from JSON, CSV, Database... data = [ {name: 'John', department: {id: 1, title: 'Engineering'}, salary: 1000}, {name: 'Jane', department: {id: 1, title: 'Engineering'}, salary: 1200}, {name: 'Boris', department: {id: 2, title: 'Accounting'}, salary: 800}, {name: 'Alice', department: {id: 3, title: 'Management'}, salary: 1500} ] data.map(&[:name]) # => ["John", "Jane", "Boris", "Alice"] data.min_by(&[:salary]) # => {:name=>"Boris", :department=>{:id=>2, :title=>"Accounting"}, :salary=>800} pp data.group_by(&[:department, :title]) # {"Engineering"=> # [{:name=>"John", # :department=>{:id=>1, :title=>"Engineering"}, # :salary=>1000}, # {:name=>"Jane", # :department=>{:id=>1, :title=>"Engineering"}, # :salary=>1200}], # "Accounting"=> # [{:name=>"Boris", # :department=>{:id=>2, :title=>"Accounting"}, # :salary=>800}], # "Management"=> # [{:name=>"Alice", # :department=>{:id=>3, :title=>"Management"}, # :salary=>1500}]} # Works with arrays, too: data.map(&:values).map(&[0]) # => ["John", "Jane", "Boris", "Alice"] # And with mixes: data.group_by(&[:department, :title]).values.map(&[0, :name]) # => ["John", "Boris", "Alice"] ``` Naked structured data seems to be a common enough thing to make working with them easier. Some prior info: * Googling it around, I found the idea was first invented [back in 2014](https://thepugautomatic.com/2014/11/array-to-proc-for-hash-access/), and another one [in 2015](https://gist.github.com/geowy/39fde25ec2966f90a54b), not sure if it was proposed on the tracker. * Other proposals for `Array#to_proc` was: to call several methods in sequence [1](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/199820), [2](https://rails.lighthouseapp.com/projects/8994/tickets/1253-arrayto_proc), and to call method with argument [1](https://www.sanityinc.com/articles/adding-array-to-proc-to-ruby/), [2](https://bugs.ruby-lang.org/issues/10829), [3](https://www.rubydoc.info/github/estum/console_utils/Array:to_proc), to call several methods in parallel: [1](https://gist.github.com/shell/1120249) Honestly, I feel that proposed usage is the most frequently needed. Also, the readability of the version seems more or less straightforward: ```ruby # Existing shortcut, for example: data.map(&:keys) # Is equivalent to data.map { |x| x.keys } # ^^^^^ -- "just remove this part" # Proposed shortcut: data.map(&[:name]) # Is equivalent to data.map { |x| x[:name] } # ^^^^^ -- "just remove this part" ``` **`dig` or `[]` alternative implementations** It is up to discussion (if the whole idea holds water) whether `dig` should be used or just `[]`. The `dig` version is convenient for nested structures but slightly breaks "equivalency" shown above, and just `[]` version will allow this: ```ruby data.map(&:values).map(&[1..-1]) # => [[{:id=>1, :title=>"Engineering"}, 1000], [{:id=>1, :title=>"Engineering"}, 1200], [{:id=>2, :title=>"Accounting"}, 800], [{:id=>3, :title=>"Management"}, 1500]] ``` Maybe, for the sake of explainability, "just `[]`" should be preferred, with digging performed by other means. -- https://bugs.ruby-lang.org/ Unsubscribe: