But this seems like a band-aid, for two reasons:
1. find_name can never return a MultiSub, and find_global doesn't
seem to work. So I can't get a handle on a MultiSub built for me by
IMCC.
2. Even if I had it, I couldn't call it, because the dispatch is
done by find_name.
Seems to me (IMHO) that the MultiSub invoke method is the right place
to do the actual dispatching, but I don't understand all the magic
involved. Also, this would seem to interact with changes to the calling
conventions [1], so perhaps this patch is premature.
Is there a MultiSub API, or one in the works?
-- Bob Rogers
http://rgrjr.dyndns.org/
[1] Leo, "[PROPOSAL] call syntax abstraction", Tue, 03 May 2005
13:58:14 +0200.
------------------------------------------------------------------------
Index: src/global.c
===================================================================
--- src/global.c (revision 8008)
+++ src/global.c (working copy)
@@ -195,6 +195,7 @@
Parrot_get_name(Interp* interpreter, STRING *name)
{
PMC *g, *pad, *current_sub, *name_space;
+ int multi_sub_p = 0;
pad = scratchpad_get_current(interpreter);
g = scratchpad_find(interpreter, pad, name);
@@ -215,6 +216,7 @@
* signature is currently passed in S1
* see also imcc/pcc.c
*/
+ multi_sub_p = 1;
g = Parrot_MMD_search_default_func(interpreter, name, REG_STR(1));
if (g)
return g;
@@ -222,12 +224,18 @@
else
return g;
}
- if (PARROT_ERRORS_test(interpreter, PARROT_ERRORS_GLOBALS_FLAG)) {
+ if (! PARROT_ERRORS_test(interpreter, PARROT_ERRORS_GLOBALS_FLAG)) {
+ return pmc_new(interpreter, enum_class_Undef);
+ }
+ else if (multi_sub_p) {
+ /* we found the name, it's just that we couldn't dispatch. */
real_exception(interpreter, NULL, E_NameError,
- "Name '%Ss' not found", name);
+ "No applicable '%Ss' method found", name);
}
-
- return pmc_new(interpreter, enum_class_Undef);
+ else {
+ real_exception(interpreter, NULL, E_NameError,
+ "Name '%Ss' not found", name);
+ }
}
/*
Index: t/pmc/mmd.t
===================================================================
--- t/pmc/mmd.t (revision 8008)
+++ t/pmc/mmd.t (working copy)
@@ -476,7 +476,7 @@
PerlSt ok 2
PerlSt ok 3
String ok 4
-Name 'p' not found/
+No applicable 'p' method found/
OUT
pir_output_is(<<'CODE', <<'OUT', "MMD on PMC types 3");
C<find_name> just searches in more namespaces, namely: lexicals,
globals, and "__parrot_core". A C<find_global> in the latter name space
should return a builtin MultiSub PMC.
> 2. Even if I had it, I couldn't call it, because the dispatch is
> done by find_name.
Well, C<find_name> should probably return the real callable sub, it it's
exexcuted inside a call sequences, that is S1 has the signature and call
arguments are already in place.
If there is no signature in S1, it should just return the MultiSub -
which it seems not do now.
*But* that is all really weak, because S1 could have any value - see
e.g. at the end of mmd_arg_tuple_func(): REG_STR(1) is cleared there for
this reason.
There is currently no real fix for this, we first have to fix calling
conventions.
> Seems to me (IMHO) that the MultiSub invoke method is the right place
> to do the actual dispatching, but I don't understand all the magic
> involved.
The MultiSub PMC is invocable and the dispatch actually happens there
for bound multi-methods. But we really should avoid dispatching inside
the MultiSub if possbile for performance reasons.
> ... Also, this would seem to interact with changes to the calling
> conventions [1], so perhaps this patch is premature.
Yeah, we should first to the calls right.
> Is there a MultiSub API, or one in the works?
You can push another candidate on it via VTABLE_push_pmc and you can
invoke it, well, it inherits from ResizablePMCArray, so you can do
everything what you can do with an array.
> -- Bob Rogers
> http://rgrjr.dyndns.org/
>
> [1] Leo, "[PROPOSAL] call syntax abstraction", Tue, 03 May 2005
> 13:58:14 +0200.
Yeah.
> --- src/global.c (revision 8008)
> +++ src/global.c (working copy)
Dunno, if we should change that now.
leo