Lizzybel was walking the corridors of North Pole Central when Steve, the Physics Elf, came up to her. “Have you seen my issue on this very nice module of yours?”, he asked.
“Oof, I guess I must have missed that, sorry!”, said Lizzybel, while thinking to herself “I really should look more at my modules every now and then”. “What is the issue about?” “Well, you know my nice App::Crag module? Well, in some cases it just generates some warnings that do not make a lot of sense in that context, so I’d like to be able to get rid of them. But I can’t”, said Steve, “It’s the CodeUnit module”.
Lizzybel tried to hide her blush, but to no avail. Steve saw that, and said: “No worries, it’s but a nuisance” and hurried away smiling, as all of the working at the North Pole don’t just work out by themselves.
CodeUnit
“Ah, yes, CodeUnit, a module that provides a unit for execution of code”, thought Lizzybel, “that cute one that I abstracted from the REPL module I worked on earlier this year. Ah, and there’s Steve‘s issue!”.
Time to look at the code! So why did setting $*ERR to /dev/null not work? Aaah… found it:
CONTROL {
when CX::Warn {
.gist.say;
.resume;
}
}
“Stupid Lizzybel“, she thought. Control messages (of which warnings are of type CX::Warn) where caught in the CONTROL block, but then output on STDOUT with .say. That should have been .note! Ok, that’s easy enough to fix.
More Options
Thinking about this some more, Lizzybel decided to make it slightly more configurable. “Why not add a :keep-warnings flag and attribute to indicate that you don’t want warnings to be shown immediately, but when you want it?”, she thought to herself. Why not indeed!
A little bit of hacking later, that piece of the code now read:
CONTROL {
when CX::Warn {
$!keep-warnings ?? @!warnings.push($_) !! .gist.note;
.resume;
}
}
So, now if we don’t want to keep warnings, they are shown on STDERR (because of .note). And if we want to keep warnings, the warning in $_ will be added to the warnings. Now for a way to get the warnings from the CodeUnit object.
method warnings() {
@!warnings ?? @!warnings.splice.List(:view) !! BEGIN ()
}
And with that it’s also possible to obtain any warnings, and reset them at the same time!
Now the only thing to do, was to update the documentation, add some more tests and release the new version of the CodeUnit module to the Raku ecosystem with mi6 release! And so it was done.
But, but, but, how?
A few hours later, Steve came running to Lizzybel, alerted by the closing of his issue, and a little short of breath, said: “That’s all very nice, and thank you. But what magic is .splice.List(:view) and BEGIN ()?”.
“Ah, yes. Maybe a little bit too core-ish for a module. But then again, that module is already bound tightly to the Rakudo implementation of the Raku Programming Language“, she answered, “so it felt ok to do that here”.
“So the .splice method without any arguments is an optimized way to both return the whole invocant array and reset that array to not having any elements. The :view named argument to the .List method is an implementation detail that provides an optimized way to change an Array into an immutable List. Provided, of course, that the underlying Array doesn’t change, and no attempts are made to change any element in the List.”, she continued. “Hmm…”, said Steve, not entirely convinced.
Lizzybel continued further: “If there are no warnings, then we could also convert the Array to a List, but that felt a bit wasteful. So why not return an empty List with () in that case?”.
“But why the BEGIN then?”, asked Steve. “Well, an empty List currently in Rakudo is equivalent to List.new, so creates a new object each time. But conceptually speaking, all empty Lists are the same. So why not always return the same one, created at compile time with the BEGIN phaser”, Lizzybel lectured. “That feels like that should be done automatically by the compiler”, said Steve, while wandering away again, busy as ever. “You’re probably right”, thought Lizzybel, “I should make that happen for RakuAST“.
Inspiration
And while Steve was walking away, Lizzybel realized she finally had a subject to write a Raku Advent post about!