From: rr.rosas@...
Date: 2015-06-16T15:52:57+00:00
Subject: [ruby-core:69612] [Ruby trunk - Feature #9108] Hash sub-selections

Issue #9108 has been updated by Rodrigo Rosenfeld Rosas.


I actually prefer the signature used by Matz two years ago in that note 18 of issue #8499, which is similar to how AS support implemented Hash#except. But since Matz seems to have changed his mind in note 20 of this ticket, I think Hash#except should have the same syntax as Hash#select.

Now, this will be a problem for lots of people using Rails since AS is not an opt-out gem in that case and it will override Hash#select changing its meaning from the Ruby bundled one.

This is the problem we get when we delegate such features to external libraries and wait for them to become popular. Once they are popular and you consider the feature and decide the behavior in the gem is not exactly the desired one we have a problem... It would be so much nicer if we could have decided on this before it was implemented in AS...

In AS except is implemented as dup.except!:

https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/except.rb

~~~
def except!(*keys)
  keys.each { |key| delete(key) }
  self
end
~~~

It uses the signature used in Matz' Note 18 of issue #8499, from 2 years ago...

----------------------------------------
Feature #9108: Hash sub-selections
https://bugs.ruby-lang.org/issues/9108#change-52953

* Author: Tom Wardrop
* Status: Open
* Priority: Normal
* Assignee: Yukihiro Matsumoto
----------------------------------------
Hi,

I seem to regularly have the requirement to work on a sub-set of key/value pairs within a hash. Ruby doesn't seem to provide a concise means of selecting a sub-set of keys from a hash. To give an example of what I mean, including how I currently achieve this:

```ruby
    sounds = {dog: 'woof', cat: 'meow', mouse: 'squeak', horse: 'nay', cow: 'moo'}
    domestic_sounds = sounds.select { |k,v| [:dog, :cat].include? k } #=> {dog: 'woof', cat: 'meow'}
```

I think a more concise and graceful solution to this would be to allow the Hash#[] method to take multiple arguments, returning a sub-hash, e.g.

```ruby
    domestic_sounds = sounds[:dog, :cat] #=> {dog: 'woof', cat: 'meow'}
```

I had a requirement in the current project I'm working on to concatenate two values in a hash. If this proposed feature existed, I could of just done this...

```ruby
    sounds[:dog, :cat].values.join #=> 'woofmeow'
```

You could do something similar for the setter also...

```ruby
    sounds[:monkey, :bat] = 'screech'
    sounds #=> {dog: 'woof', cat: 'meow', mouse: 'squeak', horse: 'nay', cow: 'moo', monkey: 'screech', bat: 'screech'}
```

Concise, convenient and readable. Thoughts?




-- 
https://bugs.ruby-lang.org/