TypeError: can't convert into Array
-
@thomthom said:
I got a custom class inherited that include Enumerable. The class also has a
#to_amethod.
...
Granted it's not an Array, but it says it cannot convert the object - which makes me wonder why since it has an#to_amethod.The
#to_amethod can come from more than one ancestor.For instance... the basic source of the
#to_amethod, comes fromObjectwhich states:
@unknownuser said:Returns an array representation of obj. For objects of class
Objectand others that don’t explicitly override the method, the return value is an array containingself. However, this latter behavior will soon be obsolete.
This implies that custom classes need to override the#to_amethod, so Ruby can know how to do the conversion.OR... the
#to_amethod can come fromArray, if the custom class, is some descendant level subclass ofArray. Which, referring to the docs:
@unknownuser said:Returns
self. If called on a subclass ofArray, converts the receiver to anArrayobject.
Note: ThatArrayitself, hasEnumerablemixed in, but it appears (looking at the C source,) that the "mixing" is done first.. then theArrayclass definition overrides the method inherited fromEnumerable, with it's own edition of the method. -
@jim said:
I think Enumerable requires that your class implement a
.eachmethod. Some Enumerable methods also need a<=>method (comparison) defined.I do have an .each method implemented. But in any case would that matter for converting to an Array?
I manually added an #to_a method to my that returns an array. So I don't understand why it raises this error...
-
You need to
yieldin your.eachiterator.Something like this (not tested.)
@entities.each{|e| yield(e)}See also: block_given?
Here's a related article about the performance of passing blocks: http://mudge.github.com/2011/01/26/passing-blocks-in-ruby-without-block.html
-
@thomthom said:
I manually added an
#to_amethod to my [class] that returns an array. So I don't understand why it raises this error...Is the superclass one of those API C++ collection classes ? Most of these give us problems when we try to subclass them.
-
@jim said:
You need to
yieldin your.eachiterator.It does that.
But I fail to see why
.eachgot to do with converting to an array when I have a.to_amethod ... ? I've been searching for info on it, but I cannot find anything. -
@thomthom said:
It does that.
Sorry, I was looking at your latest bitbucket repo, which must not be your latest version.
-
No - it's still on my computer. A larger rewrite. The one at the repo was just an early framework WIP.
-
A simplified example:
<span class="syntaxdefault"></span><span class="syntaxkeyword">class </span><span class="syntaxdefault">Foo</span><span class="syntaxkeyword">; </span><span class="syntaxdefault">def to_a</span><span class="syntaxkeyword">; [</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">2</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">4</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">]; </span><span class="syntaxdefault">end</span><span class="syntaxkeyword">; </span><span class="syntaxdefault">end</span><span class="syntaxkeyword">;<br /></span><span class="syntaxdefault">nil<br /><br />f</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">Foo</span><span class="syntaxkeyword">.new<br /></span><span class="syntaxcomment">#<Foo;0x15259760><br /><br /></span><span class="syntaxdefault">x</span><span class="syntaxkeyword">=[</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">4</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">5</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">6</span><span class="syntaxkeyword">]<br />[</span><span class="syntaxdefault">3</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">4</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">5</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">6</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">x </span><span class="syntaxkeyword">| </span><span class="syntaxdefault">f<br />Error</span><span class="syntaxkeyword">; </span><span class="syntaxcomment">#<TypeError; (eval);155;in `|'; can't convert Foo into Array><br /></span><span class="syntaxkeyword">(eval);</span><span class="syntaxdefault">155<br /></span><span class="syntaxkeyword">(eval);</span><span class="syntaxdefault">155</span>Off course,
x | f.to_aworks, but since the error message indicate some conversion was tried, I wonder why the.to_amethod wasn't used. -
use
.to_aryalthough I don't have a good explanation yet.class Foo def to_ary [1,2,3,4,5] end endThis is as close to an explanation as I could find: http://stackoverflow.com/questions/766712/make-an-object-behave-like-an-array-for-parallel-assignment-in-ruby/768201#768201
-
Thanks!
@unknownuser said:
Returns a new array. In the first form, the new array is empty. In the second it is created with size copies of obj (that is, size references to the same obj). The third form creates a copy of the array passed as a parameter (the array is generated by calling to_ary on the parameter). In the last form, an array of the given size is created. Each element in this array is calculated by passing the element’s index to the given block and storing the return value
So it appears what happens is not that
f.to_ais called, but insteadArray.new( f )- andArray.newuses.to_ary. -
@thomthom said:
So it appears what happens is not that
f.to_ais called, but insteadArray.new( f )- andArray.newuses.to_ary.Actually (if you use the CHM Ruby refdoc,) the source shows that the
#|method explicitly calls:
%(#0000BF)[arg2 = to_ary(arg2);]
ie, it makes a copy of the second arg to use locally (within its body.)
Advertisement