Issue #7657 has been reported by Nevir (Ian MacLeod). ---------------------------------------- Bug #7657: Array#& doesn't accept Enumerables https://bugs.ruby-lang.org/issues/7657 Author: Nevir (Ian MacLeod) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin12.1.0] 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#&?
on 2013-01-06 01:01
on 2013-01-06 01:03
Issue #7657 has been updated by Nevir (Ian MacLeod). Err, I mean it looks like it's similar to http://bugs.ruby-lang.org/issues/1028 ---------------------------------------- Bug #7657: Array#& doesn't accept Enumerables https://bugs.ruby-lang.org/issues/7657#change-35224 Author: Nevir (Ian MacLeod) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin12.1.0] 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#&?
on 2013-01-06 12:36
Issue #7657 has been updated by Eregon (Benoit Daloze). Assignee set to matz (Yukihiro Matsumoto) > Would it make sense for Enumerable to implement to_ary as well? Matz is not agreeing as you see in #1893: " Implicit conversion methods such as #to_ary and #to_str should be defined only when the object provides (almost) equivalent behavior (i.e. method set). Enumerable and Array are not the case. " > Or is this purely a bug in Array#&? Array#& (as well as #|, #-, #uniq and #uniq!) compare elements using #hash and #eql? as they build an Hash for performance reasons (O(m+n) instead of O(m*n), m=size of self, n=size of other array (or self in case of #uniq{,!})). This is still not documented however for some of these methods, I'll try to fix this. I think the reason this is done is semantically it makes less sense to have an intersection of an Array and an Enumerable. You would not have the reverse, as Enumerable does not have set-like methods (Array is already stealing a bit of Set in this regard because it is very practical). As an illustration, [1,2,3] + enumerable raises an error as intended (unless enumerable implements #to_ary). Too loose conversion is dangerous (for example IO#each will only yield once the lines). It could be done though at the expense of using #each instead of directly iterating on the Array structure, or converting with #to_a. I am not sure the gain of having the implicit #to_a would be clear, so I propose to use [1,3,5] & Thing.new.to_a in your case. About #1028, it was just a bug in the way of checking whether an argument is an Array or not, the code handling Enumerable was already there (that code is actually almost duplicated with enum_take()). ---------------------------------------- Bug #7657: Array#& doesn't accept Enumerables https://bugs.ruby-lang.org/issues/7657#change-35233 Author: Nevir (Ian MacLeod) Status: Open Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: Target version: ruby -v: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin12.1.0] 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#&?
on 2013-01-07 02:27
Issue #7657 has been updated by Nevir (Ian MacLeod).
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 a
subclass of Array?
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> def to_ary
irb(main):007:2> self
irb(main):008:2> end
irb(main):009:1> end
irb(main):010:0> Array(Thing.new)
TypeError: can't convert Thing to Array (Thing#to_ary gives Thing)
irb(main):011:0> [1,3,5] & Thing.new
TypeError: can't convert Thing to Array (Thing#to_ary gives Thing)
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.
https://github.com/ruby/ruby/blob/trunk/array.c#L3856
It doesn't seem like that code needs to assert that the input is an
array at all except to avoid message dispatch overhead - ary_add_hash is
also just doing a standard for loop, from what I can tell:
https://github.com/ruby/ruby/blob/trunk/array.c#L3736
Maybe it makes more sense to build the hash via #each (or use the
existing functions if the input is an Array, to preserve performance)?
----------------------------------------
Bug #7657: Array#& doesn't accept Enumerables
https://bugs.ruby-lang.org/issues/7657#change-35238
Author: Nevir (Ian MacLeod)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version:
ruby -v: ruby 1.9.3p125 (2012-02-16 revision 34643)
[x86_64-darwin12.1.0]
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#&?
on 2013-01-25 04:18
Issue #7657 has been updated by ko1 (Koichi Sasada). Target version set to next minor ---------------------------------------- Feature #7657: Array#& doesn't accept Enumerables https://bugs.ruby-lang.org/issues/7657#change-35605 Author: Nevir (Ian MacLeod) Status: Open Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: 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#&?
on 2013-01-25 07:18
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#&?
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.