I realize this is a side effect of the fact that method names are actually strings, but it's an unfortunate result.

If I have a little bit of code that calls a method without quotes around the name of the method, it calls the method (prints out "Boojum"), exactly as expected:

.sub main :main
    newclass $P1, 'Thingy'
    $P2 = new 'Thingy'
    $P2.snark()
    end
.end

.namespace [ "Thingy" ]

.sub snark method
    print "Boojum\n"
.end

But, if I were to foolishly have a local PMC variable of the same name as the method in the same compilation unit as the method call, then it tries to invoke the local variable:

.sub main :main
    newclass $P1, 'Thingy'
    $P2 = new 'Thingy'
    .local pmc snark
    snark = new PerlArray
    $P2.snark()
    end
.end

And I get the error:

    invoke() not implemented in class 'PerlArray'

If the local variable happens to be a string, it treats the string as the name of the method and calls that. So if the string happens to be "snark" it calls the snark method and prints out "Boojum", otherwise it fails (because Thingy doesn't have any other methods, so any other method name is not found).

.sub main :main
    newclass $P1, 'Thingy'
    $P2 = new 'Thingy'
    .local string snark
    snark = "snark"
    $P2.snark()
    end
.end

There's an easy way to ensure the clash between method names and local variables never happens: always wrap the method name in quotes. This will never try to invoke the local snark variable, because it knows the method name is a literal string.

.sub main :main
    newclass $P1, 'Thingy'
    $P2 = new 'Thingy'
    .local pmc snark
    snark = new PerlArray
    $P2."snark"()
    end
.end

So, my question is, should we prevent the obj.method() syntax from ever being interpreted as object."method"()? It's nice convenient syntax, but makes for some pretty nasty collisions. Or, maybe there's another solution, like requiring some explicit way of marking when obj.method() is doing anything other than obj."method"(). (That at least has the advantage of making the common case the default.)

And, yeah, I just spent some time debugging a bit of code that read something like:

.local pmc children
children = node.children()

Allison

Reply via email to