Self-referring labels
Lizmat kindly allowed Label
to expose its file and line-number. That is handy if we want to convey messages about the code itself, without having to worry about edits invalidating our line-numbers. The first use case that came to mind are lightweight singletons that are easy to find.
barcode: Nil;
qrcode: Nil;
say [barcode ~~ qrcode, barcode === qrcode, barcode =:= qrcode]; # [False False False]
put barcode; # barcode ../label-introspection.raku:16
This might be handy when sending messages through a Channel
.
my $ch = Channel.new;
start {
HERE: Nil;
THERE: Nil;
$ch.send(.item) for ((1, 2, HERE, THERE) xx ∞).flat;
}
.put for @$ch;
# OUTPUT: 1
# 2
# HERE ../label-introspection.raku:24
# THERE ../label-introspection.raku:25
# …
If those signals end up in a Str
unintended, we have a good chance to find the source of the error, even when we have to look at the sender-end of a Channel
.
We can also create error messages that point to a different line then a stacktrace might.
sub may-return-nil { }
ENIL: my $var is default(Failure.new(ENIL)) = may-return-nil;
say $var;
EWHOOPSY: fail(EWHOOPSY);
CATCH {
when X::AdHoc && .payload ~~ Label {
put "WELP! I encountered {.name} in {.file}:{.line}" with .payload;
}
}
POD doesn’t allow us to do compile time interpolation (yet). Since it is made up of Array
s, we can cheat.
DOCLABEL: sub described {
}
=begin pod
Sub described is defined in L<PLACEHOLDER>.
=end pod
CHECK $=pod[0].contents[0].contents[1] = DOCLABEL.&{.file ~ ':' ~ .line};
say $=pod;
# OUTPUT: [Pod::Block::Named{:name("pod")}
# Pod::Block::Para
# Sub described is defined in
# ../label-introspection.raku:31
# .
# ]
There are quite a few things hidden in CORE and I don’t like to use nqp::attr
to get hold of them. A public interface is better then an accidental one. The former make way better idioms.