On 29/07/2014 04:44, Marvin Humphrey wrote:
Hmm, this would mean that an object can have two distinct methods with the
same name which get invoked in different contexts: in C-space, one method
gets called, while in Perl-space, another one gets called.

I feel like that makes it harder to reason about the class -- when you talk
about calling "do_stuff" on an object, which "do_stuff" are you referring to?

It wouldn't be confusing to have two different methods for different contexts
if they were conspicuously scope-limited by a `private` qualifier or something
similar.  But instead what differentiates these methods from other methods
might be quite subtle: returning `char*`, or accepting an argument of type
`void*`.

Another item worth noting is that the proposed behavior change optimizes for a
different failure mode.  The current behavior protects inquisitive hackers
attempting to override a method they "shouldn't" know about from silent
failure.  The proposed change protects innocents who don't know about a hidden
method from noisy failure.

Can you provide a concrete example?

An example would be a Clownfish class that implements a helper function that can't be mapped to Perl for some reasons. If a Perl subclass tries to implement the same helper, things will fail.

I agree that it's confusing that methods would live in different contexts just because of their signature. To fix this, I propose to force methods to be declared private if they can't be mapped to Perl. If a non-private method can't be mapped, the Clownfish compiler would die with an error message suggesting to make the method private.

All these issues aren't important for a Clownfish release. I created a new branch 'overridden_aliases' yesterday to fix some issues when overriding aliased methods from Perl. There are similar issues when overriding excluded methods. The current implementation allows to override private or excluded methods. This is something I want to fix before release. The question above just popped up when looking at the code.

There is also a minor inconsistency in the functions that map a method's return type for XSUBs and callbacks. In CFCPerlTypeMap_to_perl which is used for XSUBs we have this piece of code:

    else if (CFCType_is_composite(type)) {
        if (strcmp(type_str, "void*") == 0) {
            // Assume that void* is a reference SV -- either a hashref or an
            // arrayref.
            result = CFCUtil_sprintf("newRV_inc((SV*)%s)", cf_var);
        }
    }

The code in CFCPerlMethod_callback_def doesn't support 'void*' return types. Assuming that void pointers are a reference SV looks a bit fragile to me. Are there any places where we rely on this behavior?

Nick



Reply via email to