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