On Monday 20 November 2006 14:20, Patrick R.Michaud wrote:

> I don't seem to be able to use iterators on subclasses of
> ResizablePMCArray.

Here's a better patch, but it appears to tickle a bug in Data::Dumper.  I'm 
not sure what the right fix is there.

I'm not a big fan of my implementation here, but this was the least invasive 
strategy I could find.  A better fix would be twofold:

- add a role for "iterable"
- fix the does_isa() mess in the Default PMC.  There's a comment in there 
about how it doesn't respect mro, and it's clear that it doesn't.  However, I 
don't want to duplicate the MRO logic I put in ParrotObject, but I ran into 
segfaults when I put it in Default.

I suspect this also is a symptom of the problem that Parrot's never quite sure 
how ParrotObject interacts with other PMCs.

I also worry somewhat that having does fall back to isa is backwards, but 
that's an even bigger change.

-- c
=== src/pmc/iterator.pmc
==================================================================
--- src/pmc/iterator.pmc	(revision 590)
+++ src/pmc/iterator.pmc	(local)
@@ -502,7 +502,9 @@
         PMC * const key = PMC_struct_val(SELF);
         PMC * const agg = PMC_pmc_val(SELF);
         PMC *ret;
-        if (PObj_is_object_TEST(agg)) {
+        if (PObj_is_object_TEST(agg)
+            && ! (VTABLE_does(INTERP, agg, const_string(INTERP, "array"))
+            ||    VTABLE_does(INTERP, agg, const_string(INTERP, "hash")))) {
             REG_PMC(2) = agg;
             return VTABLE_shift_pmc(INTERP, key);
         }
=== src/pmc/parrotobject.pmc
==================================================================
--- src/pmc/parrotobject.pmc	(revision 590)
+++ src/pmc/parrotobject.pmc	(local)
@@ -636,6 +636,26 @@
         set_attrib_flags(SELF);
         PObj_is_object_SET(SELF);
     }
+
+    INTVAL does(STRING *interface) {
+        PMC *mro, *parent;
+        INTVAL n, i;
+    
+        if (SUPER(interface))
+            return 1;
+
+        mro = SELF->vtable->mro;
+        n   = VTABLE_elements(INTERP, mro);
+
+        for (i = 0; i < n; i++) {
+            parent = VTABLE_get_pmc_keyed_int(INTERP, mro, i);
+
+            if (VTABLE_does(INTERP, parent, interface))
+                return 1;
+        }
+
+        return 0;
+    }
 }
 
 /*

Reply via email to