On 5/10/07, via RT Alek Storm <[EMAIL PROTECTED]> wrote:
# New Ticket Created by "Alek Storm"
# Please include the string: [perl #42919]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=42919 >
Because PIR can't tell the difference between invoking an object PMC and
invoking a sub PMC, it doesn't generate a correct set_args when an object is
invoked. Since the 'invoke' override is a method, it expects the current
object to be the first parameter. There are currently two workarounds: pass
the current object explicitly as the first parameter, or don't declare
'invoke' as a :method. The first is inconvenient and unintuitive, and the
second means 'invoke' doesn't get access to its own object.
Example code for bug:
.sub _ :main
$P0 = newclass "Foo"
$P1 = new "Foo"
$P1("bar")
.end
.namespace ["Foo"]
.sub 'invoke' :method :vtable
.param string bar
say bar
self.'baz'()
.end
.sub 'baz' :method
say "baz"
.end
Output:
too few arguments passed (1) - 2 params expected
current instr.: 'parrot;Foo;invoke' pc 16 (/home/alek/test2.pir:8)
called from Sub '_' pc 11 (/home/alek/test2.pir:4)
I've attached a patch that fixes this by grabbing the args signature inside
delegate.invoke() and unshifting an arg of type PARROT_ARG_PMC |
PARROT_ARG_OBJECT. It also modifies src/inter_call.c to handle this by
setting the arg equal to interp->current_object, and enums.h to add the new
argument flag. The tests in t/pmc/parrotobject.t have been changed to
include :method on the 'invoke' overrides, and to remove the test for
#41732, which is no longer applicable.
--
Alek Storm
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.
.sub main :main
$P0 = newclass 'Func'
$P1 = newclass 'Obj'
$P2 = new 'Obj'
$P2.'some_method'()
.end
.namespace ['Func']
.sub invoke :vtable :method
.param pmc an_arg
print 'vtable invoke with self = "'
print self
print '", arg = "'
print an_arg
say '"'
.end
.sub get_string :vtable
.return ('an instance of Func')
.end
.namespace ['Obj']
.sub find_method :vtable :method
.param string meth_name
print 'find_method "'
print meth_name
print '" from "'
print self
say '" (***)'
.local pmc func
func = new 'Func'
.return (func)
.end
.sub get_string :vtable
.return ('an instance of Obj')
.end
=====
I expect as output:
find_method "some_method" from "an instance of Obj" (***)
vtable invoke with self = "an instance of Func", arg = "an instance of Obj"
I don't know about the internals of parameter passing, it could be
that it's not possible.
The current output is:
find_method "some_method" from "an instance of Obj" (***)
vtable invoke with self = "an instance of Func", arg = "" (***)"
Some strange things are happening with registers.
--
Mehmet