hi,

I have a question concerning invoking objects represented at runtime by ParrotObjects. First an introduction (quite long, but then you get the picture of what I'd like to do).

Suppose I have this class Foo. Foo has a number of operations, like adding, etc. In fact, the operations allowed are all overridable operations, as described in http://www.parrotcode.org/docs/pdd/pdd15_objects.html (so, __add, __invoke, etc.)

This class Foo is currently implemented as a class, (in PIR, not a pmc). (
(so that means

   newclass $P0, "Foo"
)

This means the objects during runtime are represented by ParrotObjects.

The user of this class can override the default behaviour of the above mentioned operations. Default behaviour here just means "Uhoh cannot <insert operation name here> to this object!".

The user can override this behaviour for certain instances of this class Foo, so this behaviour must be set on a per-instance base.

When I override the "__invoke" operation like this:

(I know doing it like this means the behaviour is changed for all objects of Foo, but the check whether it's overriden for *this* particular object, is done in __invoke. )

   .namespace ["Foo"]

   .sub __invoke method
       # check whether calling this object makes sense: for some
       # objects of Foo it will,
       # for others it won't.
       # if it can't do this:
       print "Uhoh! cannot 'invoke' this object of Foo!"
   .end

   # to get the picture; another operation that may or may not
   # be implemented for this particular object
   .sub __add method
      # check whether adding this object makes sense: for some
      # objects of Foo it will,
      # for others it won't.
      # if it can't do this:
      print "Uhoh! cannot 'add' this object of Foo!"
   .end

   #
   # et cetera.

Well that was the introduction :-). Now my problem/misunderstanding:

When I do this:

   new $P0, "Foo"
$P0() ## my goal was to have the MMD system let call __invoke on this object...

I get this message:

   Can't create new ParrotObjects - use the registered class instead

Checking in the code for ParrotObject.pmc, it seems this error message is given to prevent users of calling invoke on 'objects'. THe only way to implement the desired behaviour (as I described above) seems to implement my class Foo as a PMC (that's my guess), because Foo is now an instance of the ParrotObject pmc (right?). (Implementing it as a pmc is the plan for the future, because it is faster, but this is easier for testing/debugging etc.)

Is there any way I can acquire the desired behaviour without writing the Foo pmc (but just leaving it implemented as a class defined in PIR) ?
I don't quite see the problem that is suggested in parrotobject.pmc:

   void* invoke(void* next) {
       SELF.init();
       return next;
   }

and the comments for init() are:
Raises an exception to make sure all users call C<new> on the registered
   class PMC and not the ParrotObject itself.




By the way:

  $P0."__invoke"()

*does* work, but I don't like this syntax (not in this case), because at compile time I don't know what operations are allowed on an object (it depends on the user what operations he defines for that particular object). So I just like to do emit "$P0 + $P1" when translating "a + b" and emit "$P0()" when translating "a()". So, leaving the magic to the MMD system makes things easier.

thanks,
klaas-jan


Reply via email to