On 09.08.2009 22:49, Erik Michaels-Ober wrote:

>> Second, I would argue that there should be + (plus), - (minus), and &
>>> (ampersand) methods on hashes, that function the same way they do for
>>> arrays
>>> (concatenation, difference, and intersection, respectively).
>>>
>> Hash is a very flexible citizen, though. It plays many roles. So how does
>> this come out:
>>
>> {0=>1, 1=>0} - {1=>1} = ?
>>
>> {0=>1, 1=>0}
>> # if you look at a hash as a set of pairs
> 
> 
> I do look at Hash as a set of pairs and I would consider the other uses you
> cite to be "non-standard". The first line of RDoc for the class states: "A
> Hash is a collection of key-value pairs."

You omit a very important additional property: no key can occur twice in 
a Hash.  Actually I would consider at least option one and three of 
Joel's list as common usage of a Hash.

> I would argue it's better for +, -, and & to be defined for the standard use
> case than to remain undefined in the language.  Those using Hash in a
> non-standard way can simply avoid these methods.

The problem is that there is no standard use case.  Removing based on 
the identical pair seems to me as valid as removing based on the key 
only as implementations for Hash#-.

Concatenation does not make sense with an unordered collection.  See 
also various discussions why Hash does not (or rather did not) implement 
#hash and #eql? as many people expected.

> You could just as well argue that someone might want [6] - [1] to return
> [5], but that wouldn't make sense given that "Arrays are ordered,
> integer-indexed collections of any object."

Well, the implementation of Array#- does not fit there well, does it? 
Because it works like set substraction while Array#+ works as array 
concatenation - not very consistent either - but apparently useful.

> Any objections to nil.to_hash?
> 
> Note: in the example I meant to type (hash_or_nil || {}).rehash instead of
> (hash_or_nil || nil).rehash

What other classes do implement to_hash?  In 1.9.1:

irb(main):007:0> ObjectSpace.each_object(Module) {|cl| p cl if 
cl.instance_methods.include? :to_hash}
Hash
=> 407
irb(main):008:0>

Btw, invoking x.to_hash is not a cast.  First, there are no casts in 
Ruby because variables do not have types and second, to_hash is an 
ordinary method.  Casts on the other hand are usually not implemented 
via ordinary methods.  (In C++ for example casts are operators which can 
be overloaded.)

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/