Hi,

I have a class A, that has an object of class B as an attribute.
I've overriden the add() method of class A, and I want to let class B handle the actual work. The idea is to make this class B replacable by the user, so he can override the behaviour of a certain object of A, without disturbing other objects of A.

so, pseudocode may look like this:

class A
{
   B b;
method init()
   {
      b = new B();
   }

   method __add(left, right)
   {
      b.__add(left, right); //***
} }

class B
{
   method __add(left, right)
   {
      // standard behaviour:
      print("No __add() defined for objects of <left>");
   }

   method someCustomAddMethod(left, right)
   {
      print("Ok!");
   }
}

function main()
{
   A a1, a2, sum;
sum = a1 + a2; }

It seems that at the line, marked with "//***", not the __add method of b is called, but that A's __add method is called again. However, when this call is replaced by a call to b."someCustomAddMethod"(left, right), everything is working as expected.

I translate the above pseudo code to: (which runs ok, except for the "//***"-marked line)


################
.sub main
   # create the classes
   newclass $P0, "A"
   newclass $P1, "B"
addattribute $P0, "b"
   # make sure there's an constructor for A creating its member variable b.
   new $P10, .String
   set $P10, "_new"
setprop $P0, "BUILD", $P10
   # create instances of a, and add them
   find_type $I0, "A"
   new $P20, $I0
   new $P21, $I0
   new $P22, $I0
   $P22 = $P20 + $P21
end
.end

.namespace ["A"]

# constructor for A
.sub _new method find_type $I0, "B"
   new $P0, $I0
setattribute self, "b", $P0 .end

.sub __add method
   .param pmc self
   .param pmc left
   .param pmc right

   # get fully qualified named attribute b
   getattribute $P1, self, "A\0b"

   # now, $P1 should hold the "b", right?
   # checking by:
   print $P1
   # works, 'cause it calls the __get_string() method of B

#scenario 1: doesn't work
# call B's __add() method #$P1."__add"(left, right) #//*** this does not work!

#scenario 2: works ok

   $P1."someCustomAddMethod"(left, right)

.end

.namespace ["B"]
.sub __add method printerr "No __add() defined for objects of <left>"
.end

.sub someCustomAddMethod method
   printerr "Adding with custom method"
   # ...
.end

.sub __get_string method
   print "this is B"
.end
########################################

The error I get is this:

[EMAIL PROTECTED]:~/parrot$ parrot cltest.pir
No such attribute 'A\0b'
current instr.: 'A :: __add' pc 64 (cltest.pir:36)
called from Sub 'A :: __add' pc 95 (cltest.pir:40)
called from Sub 'main' pc 31 (cltest.pir:15)

It looks as if the .invocant is not set properly, effectively calling the __add() method on the wrong object (self, instead of b).

Now, the trouble is, it's not doing what I'd expected. It may of course well be that I'm not thinking right, and I wrote buggy code. OTOH, it may be it's a bug. Just checking here.

thanks,
klaas-jan






Reply via email to