On Fri, 31 Dec 2004, Leopold Toetsch wrote: > Simon Glover <[EMAIL PROTECTED]> wrote: > > > new P0, .ResizablePMCArray > > set P0, 1 > > clone P1, P0 > > eq P0, P1, L1 > > print "not " > > L1: print "ok" > > print "\n" > > end > > > prints "not ok". > > This is a different issue. The ResizablePMCArray doesn't properly > inherit the is_equal multi method from FixedPMCArray and as far as I can > see, there is no Undef involved at all. Empty array slots are filled > with PMCNULL, which is a singleton. The example works for FixedPMCArray.
In the case of the ResizablePMCArray, the Undef comes into it because of this loop in is_equal(): for (j = 0; j < n; ++j) { PMC *item1, *item2; item1 = DYNSELF.get_pmc_keyed_int(j); item2 = VTABLE_get_pmc_keyed_int(INTERP, value, j); if (item1 == item2) continue; if (!mmd_dispatch_i_pp(INTERP, item1, item2, MMD_EQ)) return 0; } and this code in get_pmc_keyed_int: data = PMC_data(SELF); if (data[key] == PMCNULL) data[key] = pmc_new(INTERP, enum_class_Undef); return data[key]; When is_equal calls get_pmc_keyed_int to do the comparison, it creates and returns an Undef PMC, rather than simply returing PMCNULL, and since Undef != Undef, this ultimately causes the comparison to fail. In the case of FixedPMCArray, the test passes because the implementation of get_pmc_keyed_int doesn't have the test for PMCNULL -- instead, it just does: data = (PMC **)PMC_data(SELF); return data[key]; Hence, if the entry is PMCNULL, the code actually returns PMCNULL, and since PMCNULL == PMCNULL, the comparison succeeds and the test passes. I guess the real question is should we be creating that Undef PMC; i.e. should fetching an undefined element return a fully-fledged Undef value, or simply a PMCNULL, which may later be promoted to a real Undef? Simon