I see. But it sould still be considered as a bug.
I modified your class A as following:
class A {
class B {
mixed b() {
return A.C;
//return C;
}
}
class C {
}
}
Since C is a constant of class A, B.b() reference a constant of its parent scope.
Why it should be considered as whatever PROGRAM_USES_PARENT ?
I think A.C has the same position of constants such as "hello", 1,2,3 ...
If the class referenced A.C become a function, then the classes referenced any
constant string or number should be function too.
"A program is no more a constant because it reference another constant"? it's a
joke!
> Date: Tue, 25 Aug 2009 15:32:57 +0200
> From: <grubba[at]roxen.com>
> To: <peterpan[at]wukong.com>
> CC: <pike[at]roxen.com>
> Subject: Re: Bug when using program as key of mapping
>
> On Tue, 25 Aug 2009, ¹ùÑ©ËÉ wrote:
>
> > $ cat t.pike
> >
> > mapping m=([]);
> > class SomeClass{}
> > class OutsideClass{
> > class InsideClass(string|void dir,object|void room_design){
> > array t(){
> > return ({});
> > SomeClass; //Line A
> > }
> > };
> >
> > void create()
> > {
> > m[object_program(InsideClass("haha",SomeClass()))]=1;
> > }
> > }
> >
> > void main()
> > {
> > object ob=OutsideClass();
> > write("should be 1: %O\n",m[OutsideClass.InsideClass]);
> > }
> >
> > $ pike t.pike
> > Sould be 1: 0
> >
> > If remove Line A, the result is good:
> >
> > $ pike t.pike
> > Sould be 1: 1
>
> The reason for the difference is that in the first case InsideClass gets
> the flag PROGRAM_USES_PARENT set, since it refers (even though via
> ultimately dead code) to a symbol in a parent scope. When
> PROGRAM_USES_PARENT is set, Pike keeps track of the context from which
> the class came.
>
> Consider the following case:
>
> class A {
> class B {
> mixed b() { return C; }
> }
> class C {}
> }
>
> class D {
> inherit A;
> class C {
> inherit A::C;
> void c() {}
> }
> }
>
> int main()
> {
> object a = A();
> object d = D();
>
> werror("function_object(a->B):%O\n", function_object(a->B));
> werror("function_object(a->C):%O\n", function_object(a->C));
> werror("function_object(d->B):%O\n", function_object(d->B));
> werror("function_object(d->C):%O\n", function_object(d->C));
>
> object b = a->B();
> werror("indices(b->b()()):%O\n", indices(b->b()()));
>
> object b2 = d->B();
> werror("indices(b2->b()()):%O\n", indices(b2->b()()));
>
> werror("function_object(b->b()): %O\n",
> function_object(b->b()));
> werror("function_object(b2->b()):%O\n",
> function_object(b2->b()));
> }
>
> Here the class A.B refers to the class A.C and thus gets
> PROGRAM_USES_PARENT set. The class A.C on the other hand
> does not refer to anything. The class D.B keeps its flag,
> and the class D.C gets the flag set, since it refers to
> A.C via the inherit in D. The example thus outputs:
>
> function_object(a->B):/main()->A()
> function_object(a->C):0
> function_object(d->B):/main()->D()
> function_object(d->C):/main()->D()
> indices(b->b()()):({ })
> indices(b2->b()()):({ /* 1 element */
> "c"
> })
> b->b() == b2->b():0
> function_object(b->b()): 0
> function_object(b2->b()):/main()->D()
>
> In your example, the program inserted in the mapping has a parent object
> (ob), while the lookup is done with a program lacking a parent object.
> If you change the last line to
>
> write("should be 1: %O\n",m[ob->InsideClass]);
>
> You will get the expected 1 in the output, although if you have multiple
> instances of OutsideClass you will still run into problems, since you will
> have one InsiceClass for each object.
>
> > Xuesong Guo
>
> --
> Henrik Grubbström <grubba[at]roxen.com>
> Roxen Internet Software AB
_________________________________________________________________
More than messages–check out the rest of the Windows Live™.
http://www.microsoft.com/windows/windowslive/
|