Sherm Pendley wrote:
On Wed, Nov 10, 2010 at 3:33 PM, Matt Sergeant <> wrote:
Can you explain the need for the isSuperMethod flag? Surely you just
dispatch the method to whichever object is in $self and Objective C knows
how to climb it's own inheritance tree?

Yes, but the compiler knows that by emitting different code when super
is the target, so [self foo] and [super foo] compile down to calls to
objc_msgSend() and objc_msgSendSuper(), respectively.
CBCallNativeMethod() needs to know whether it's been called via SUPER
for the same reason, to decide which dispatch method to call.

OK, I found an example where SUPER:: is used (TransparentWindow), and came up with this version instead:

sub NSObject::AUTOLOAD {
    my $subName = $NSObject::AUTOLOAD;
    my $selString = $subName;
    $selString =~ s/^\w+:://;
    $selString =~ s/_/:/g;
    if (@_ > 1 && $selString !~ /:$/) {
        $selString .= ':';
    my $isSuperMethod = undef;
    if ($selString =~ s/^SUPER:://) {
        $isSuperMethod = 1;
    # Strip away the class name from the selector
    $selString =~ s/^.*::(.*)/$1/;
    my $sub = sub {
        my $self = shift;
        my $returnObject = CamelBones::CBCallNativeMethod(
        $self, $selString, \@_, $isSuperMethod);
        if (wantarray && ref($returnObject)) {
            if ($returnObject->isa('NSArray')) {
                my @array;
                tie(@array, 'CamelBones::TiedArray', $returnObject);
            } elsif ($returnObject->isa('NSDictionary')) {
                my %hash;
                tie(%hash, 'CamelBones::TiedDictionary', $returnObject);
                return (%hash);
            } else {
                return $returnObject;
        } else {
            return $returnObject;
    if (!$isSuperMethod) {
        # don't cache calls with SUPER in - everything else we can cache...
        no strict 'refs';
        *{$NSObject::AUTOLOAD} = $sub;

Seems to work...