[Update 2010-04-03: The below post is about a bug which jnthn++ just fixed in Rakudo master. That means that the cause for the main complaint of the post — not getting any sensible error diagnostics whatsoever — has been removed. Yay!]
Help! I'm getting the error "invoke() not implemented in class 'Undef'" in my large application. What did I do wrong?
You've mistyped a class name which sits inside a namespace.
How am I supposed to figure that out?
I didn't say it was a particularly good error message.
It's like this: if you mistype a class name which is not in a namespace, you'll get an informative error message:
$ perl6 -e 'A.foo'
Could not find non-existent sub A
in Main (file src/gen_setting.pm, line 324)
However, if you mistype a class name which is in a namespace, you will get an uninformative error message:
$ perl6 -e 'A::B.foo'
invoke() not implemented in class 'Undef'
in Main (file <unknown>, line <unknown>)
So there's your error message. Linking it to the actual cause is something which you'll learn by experience.
So in that case, I don't get the name of the class which was mistyped in my program?
Correct.
And I don't get the line number of my typo?
Indeed not.
Or the file?
Right. You'll get no information about the location of the typo.
Is that intentional?
Well, no. As you see from the error message above, the information is meant to be printed, but it comes out as (file <unknown>, line <unknown>)
instead.
Why?
Rakudo is built on top of Parrot. Usually, Rakudo generates its own error messages, but in some cases, Parrot will also generate an error. The error invoke() not implemented in class 'Undef'
is such a case. When a Parrot-internal error like this one occurs, Rakudo will not be able to extract the annotation information required to provide a sensible line number and file.
I... I see.
Yeah. Sorry about that.
Are you able to pick up the irony in the fact that when I use namespaces to help mitigate the complexity of my project, I end up with an error message that in fact makes it harder for me to manage the complexity of my project?
Hold on.
Yes. We are able to pick up the irony in that. Quite easily, in fact.
Consider not using namespaces at the present juncture. They are very useful, but they are also known as a frequent source of annoyances like this.
By the way, I couldn't help but note that the line number and file information in your first example doesn't make any sense either. What the heck is src/gen_setting.pm
and line 324
?
Well, uh, that's the last line of internal Rakudo code that actually has a working line-and-file annotation. It's nothing that should reach the user, really.
So that's kinda broken, too?
Annotations are currently broken, yes. Apologies.
Back to my mistyped type name. My program is distributed over fifteen modules and ten thousand lines of code. How do you propose I find my typo?
First off, we recommend that you compile often. That way, the diff from the last working code will not be too large, and you will not have to visually scan so much text hunting for your typo.
Secondly, it's often useful to have your project in a version tracker such as Git, so that you can do git diff
to see the changes against the index, or against the latest commit.
Thirdly, when all else fails, you can always insert print statements into your code, to try to bisect the origin of the error.
So in other words, Rakudo is no help whatsoever when this occurs?
Now, that's not quite fair. Rakudo tells you that the error occurs. That's actually useful information.
And you consider that adequate?
No, I didn't say that! No-one is happy about this situation. It's just the way things are.
So it can't be fixed?
Theoretically, yes. But not easily. Remember that the error occurs in Parrot.
Don't Rakudo and Parrot developers confer with each other?
Oh, sure we do. Do not assume that we're deliberately causing this situation. It's just that the current way Rakudo and Parrot are welded together makes the situation non-trivial to rectify.
So this problem is going to go away with the advent of the new ng
branch?
There's nothing to indicate that this would be the case. In ng
, you currently get a Null PMC access:
$ ./perl6 -e 'A::B.foo' # ng branch
Null PMC access in invoke()
current instr.: '_block14' pc 29 (EVAL_1:0)
called from Sub '!UNIT_START' pc 984 (src/glue/run.pir:17)
called from Sub 'perl6;PCT;HLLCompiler;eval' pc -1 ((unknown file):-1)
called from Sub 'perl6;PCT;HLLCompiler;command_line' pc 1489 (src/PCT/HLLCompiler.pir:794)
called from Sub 'perl6;Perl6;Compiler;main' pc -1 ((unknown file):-1)
To its credit, Rakudo ng
does provide more information in this case, but unfortunately the information is of a kind which was concealed from the user in Rakudo master
about a year ago (because it tended to be very uninformative).
Just to summarize: this all sucks, right?
That would be a succinct description of the state of this particular error message, yes.
I heard that the Perl 6 community has adopted very high standards with respect to error messages. There's talk about "awesome error messages", and last summer I was in the audience when Larry Wall demonstrated how good Perl 6 was at reporting error messages to the user. How does this error message square with all of that?
The awesome error messages are like a platonic ideal towards which all implementations aspire. Rakudo, being rooted in our imperfect physical world, doesn't always get all the way. Yet.
I'm about to go visually scan ten thousand lines of code, looking for where my error message might have originated. Any last words?
We value your efforts as an early adopter of Rakudo. Your feedback is important to us. Have a nice day.
Re:heh
masak on 2010-02-09T10:52:36
Every once in a while, I stumble on the strange and unfounded view that the Perl 6 community has walked into the mist of just specifying features and crystallizing paradigms without actually producing anything. (See, for example, here.)
That view, perhaps reasonable when coming from an outsider, still surprises and saddens me. The FAQ post shows what it's really like to be an early-adopter Perl 6 application developer today. It's very concrete, sometimes painfully so.
Sure, the class-typo error message is one of the most extreme ones, but there are hundreds of smaller annoyances of lesser dignity. The road to Perl 6 is littered with a million paper cuts.
Re:heh
patspam on 2010-02-10T04:22:59
I hope my reply didn't imply that..!
I'm just one of the (I assume) many who read Rakudo/Parrot related blog posts with a palpable sense of excitement - and in this case enjoyed the humour:) Re:heh
masak on 2010-02-10T11:56:54
Right, your reply didn't imply that. And I'm glad to hear there are people following Parrot/Rakudo progress with a sense of excitement. One sometimes forgets that, what with detractors being louder and all.
The fact is that many things are amazing. Just using the subset of Perl 6 that Rakudo provides... it's quite an experience. At the same time, it's not all roses either. If I were some kind of brainless sycophantic groupie, I would perhaps sweep the bad parts under the carpet, and wail "Rakudo is the most blatantly brilliant thing since Michael Dorn!".
But it isn't, and I don't. Instead, I try to give a sense of how frustrating and confusing it sometimes is, and how it's really everyone's and no-one's fault. I'm happy this attempt came across as having humour; that's much preferable to just being a lot of whining.
Re: since Michael Dorn...
spinclad on 2010-02-18T20:49:36
But.. but ... oh, yes, you're right. That was proto, and Austria, of course. A grateful nation still applauds. Re: since Michael Dorn...
masak on 2010-02-18T22:58:27
I want to come out and publicly defend the Nobel Peace prize committee by saying that they have seen the error of their ways after the proto nomination. That's why last year, they decided to give the prize to the president of the very peaceful United States.
I hear this year, the committee will give the prize either to Bruce Willis, or to the kind of lint one sometimes find in one's navel.