roxen.lists.pike.general

Subject Author Date
RE: Bug when using program as key of mapping 雪松 郭 <zenothing[at]hotmail[dot]com> 26-08-2009
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/