On 5/15/07, Alek Storm <[EMAIL PROTECTED]> wrote:
On 5/14/07, Mehmet Yavuz Selim Soyturk <[EMAIL PROTECTED] >
wrote:
> Should we not be able to use an object that implements 'invoke' as a
> method of another object? There is some strange behaviour when I try
> to.

I see what you're saying, and it looks like you want a functor.  We can't do
exactly what you want in that syntax, because methods are loosely tied to
objects in Parrot.  Parrot sees 'Func' as a sub, so it wouldn't make any
sense to tell the sub it's called by itself.  Regardless of what
'find_method' returns, the invocant is $P2 when you use PIR syntax.  Here's
how to get the effect you want:

.sub main :main
  $P0 = newclass 'Func'
  $P1 = newclass 'Obj'
  $P2 = new 'Obj'
  $P3 = find_method $P2, 'some_method'
  $P3.$P3()
.end

The patch has been reverted, though, so that won't work until it's fixed and
reapplied.

What I really meant is $P2.$P3() . With Allison's patch both

  (*)   $P2.'some_method'()
and
  (**)  $P3 = find_method $P2, 'some_method'
        $P2.$P3()

caused the same strange behaviour. I applied your patch, and (**)
worked as I expected. But (*) caused an error:

   too many arguments passed (3) - 2 params expected


I think that I found the problem. callmethodcc calls
VTABLE_find_method, which invokes the find_method override, which is a
PIR sub. That causes that interp->current_args gets overwritten.

I have a patch which tries to solve that problem:

--- src/ops/object.ops  (revision 18542)
+++ src/ops/object.ops  (working copy)
@@ -50,11 +50,20 @@
  PMC *method_pmc, *object;
  opcode_t *next;
  STRING *meth;
+  opcode_t *current_args;

  object = $1;
  meth = $2;
  next = expr NEXT();
+
+  /* If VTABLE_find_method calls a find_method override (which
+     is another PIR sub), interp->current_args gets overwritten.
+     We have to remember it.
+  */
+  current_args = interp->current_args;
  method_pmc = VTABLE_find_method(interp, object, meth);
+  interp->current_args = current_args;
+
  if (!method_pmc) {
    real_exception(interp, next, METH_NOT_FOUND,
        "Method '%Ss' not found", meth);


I only did it for the callmethodcc_p_sc opcode though, because I don't
know if it's the right solution. A possible problem: could
current_args get GC'd in the meantime?

--
Mehmet

Reply via email to