Issue #7657 has been updated by marcandre (Marc-Andre Lafortune).

Category set to core

Nevir (Ian MacLeod) wrote:
> Let me see if I understand the implicit conversion cases:
> 
> * If an object implements #to_ary, #to_str, etc - it is asserting that it is close enough to the desired type in behavior that we don't need to perform an explicit coercion?
> * I.e. if I implement #to_ary, I'm asserting that I behave close enough to an Array that you can just use me directly.
> 
> In that case, why is it an exception if the result of #to_ary is not an instance (or subclass) of Array?

By implementing `to_ary`, your class states must return an array because after MRI asks for implicit conversion with `to_ary, it will then access the data directly. No call to `each`, `[]` or `slice` is made.

> Re: building a Hash under the covers, the use of #hash and #eql? is primarily for the individual elements of the container?  From looking at the C source, it looks like #& is just doing a traditional for loop over the array instead of using #each

Right.

So your request was changed from a bug report to a feature request, i.e. to accept Enumerables as argument to &, |, etc.

Here's another argument in your favor:

    require 'set'
    Set[1,2,3] | (3..4) #  => #<Set: {1, 2, 3, 4}> 
       [1,2,3] | (3..4) # =>TypeError: can't convert Range into Array

I feel it would be best to be consistent and allow Enumerable arguments too.

----------------------------------------
Feature #7657: Array#& doesn't accept Enumerables
https://bugs.ruby-lang.org/issues/7657#change-35624

Author: Nevir (Ian MacLeod)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


This seems similar to http://bugs.ruby-lang.org/issues/6923

Example:

    irb(main):001:0> class Thing
    irb(main):002:1>   include Enumerable
    irb(main):003:1>   def each(*args, &block)
    irb(main):004:2>     [1,2,3,4,5].each(*args, &block)
    irb(main):005:2>   end
    irb(main):006:1> end
    => nil
    
    irb(main):007:0> Array(Thing.new) & [1,3,5]
    => [1, 3, 5]
    irb(main):008:0> [1,3,5] & Thing.new
    TypeError: can't convert Thing into Array
    
    irb(main):009:0> Thing.class_eval do
    irb(main):010:1*   alias_method :to_ary, :to_a
    irb(main):011:1> end
    => Thing
    
    irb(main):012:0> [1,3,5] & Thing.new
    => [1, 3, 5]

Would it make sense for Enumerable to implement to_ary as well?  Or is this purely a bug in Array#&?


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