Issue #5478 has been updated by Alexey Muranov.


I've let my imagination go free and got another crazy(/stupid) idea: abandon Set, add methods to Hash, and use it as Set.

The main drawback seemed at first to be the name, but the technical term for Ruby's hash is "associative array", so there shall be no abuse of terminology if Hash class is used to represent both _sets_ and _associative arrays_.

In fact, the `#include?` instance method already exists in Hash and for "set-like" hashes it works as expected:

```
{ 1 => nil, 2 => nil, 3 => nil }.include?(2) # => true
```

To make Hash implement both sets and associative arrays, it can be made to implement first of all sets, while implementing associative arrays can be a byproduct: store associative arrays as sets in which every element is, for example, an instance of Arrow, where

```
class Arrow
  attr_reader :key
  attr_accessor :value

  def initialize(key, value=nil)
     ...
  end

  def hash
    key.hash
  end
end
```

This will make the literal syntax consistent:

```
{} == Hash.new                                                                                 # => true
{1, 2 } == { 1=>nil, 2=>nil }                                                            # => *false*
{ 1=>nil, 2=>nil }  == { Arrow.new(1), Arrow.new(2) }                     # => true
{ 1 => "a", 2 => "b" } == { Arrow.new(1, "a"), Arrow.new(2, "b") }   # => true
{ 1, 2 => "b" } == { 1, Arrow.new(2, "b") }                                       # => true
Arrow.new(2, "b") == (2=>"b")                                                          # => true
```

(Note that this is different from Ruby 1.8 interpretation of `{1, 2}`)
----------------------------------------
Feature #5478: import Set into core, add syntax
http://redmine.ruby-lang.org/issues/5478

Author: Konstantin Haase
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 3.0


=begin
A set is a central data structure. However, a lot of Ruby developers use arrays for situations where it would be more reasonable to use a set. One reason for that is that it is way easier to use Array then Set at the moment, another one is that developers are simply not aware it exists.

I propose moving Set from the stdlib to core and possibly add a syntax or a method on array for creating Set literals.

First class syntax suggestions:

    <1, 2, 3>  # might be tricky to parse
    #[1, 2, 3] # would collide with comments
    $[1, 2, 3]
    ${1, 2, 3}

Method suggestions:

    ~[1, 2, 3]
    +[1, 2, 3]

Whitespace separated String Sets could look like this:

    %w<foo bar blah> # creates an array at the moment 
    #w[foo bar blah] # would collide with comments
    $w[foo bar blah] # would collide with sending :[] to $w
    $w{foo bar blah}

    ~%w[foo bar blah] # not really shorter than using an array with strings
    +%w[foo bar balh] # not really shorter than using an array with strings

Maybe it's ok to not have a whitespace separated syntax, I'm just brainstorming here.

The issue with the method approach is that it would create an Array to send the message to first.

I favor the <1, 2, 3> syntax, possibly without the ability to create a whitespace separated version.

I'd be willing to work on a patch not only for MRI but also for JRuby and Rubinius if you would consider this to be useful.
Although I would need help with the parser.
=end



-- 
http://redmine.ruby-lang.org