An example on the 'class Signature' page appears as:
sub named(:official($private)) { "Official business!" if $private }; named :official;
<-----
Note: That's where to example ends ... there is no output described or shown.
So I typed in the code and when the method 'named' is executed it always prints "Official business!" no matter the value of $private. That is, if $private=True then invoking 'named' prints "Official business!" as you might expect but with $private=False invoking 'named' still prints 'Official business!' whereas I thought there should be no output generated. I'm missing something aren't I but what?
I see how the doc example was confusing. Here's an expanded version of that explanation:
sub named(:official($private)) {
# Inside the function, the argument the caller passed in
# is bound to the variable $private. Nothing is bound to official.
say $private;
}
# Outside the function, the caller doesn't need to care what term the
# function uses. All it needs to know is the name of the parameter – :official
named(:official('foo')); # OUTPUT: «foo»
This is especially handy when the function is in a different module – the owner of the function can refactor the name of the their $private
argument without breaking any external callers. And, if they think of a better name for external callers to use, they can even add that without breaking backwards compatibility: sub named(:official(:better-name(:$private))) { … }
lets callers use either :official
or :better-name
as the parameter name, without having any impact on the variable name inside the function.
Does that make more sense?
Oh, and one note regarding this:
if $private=True then invoking 'named' prints "Official business!" as you might expect
If I'm understanding you correctly, you mean writing something like
sub named(:official($private)=True) { "Official business!" if $private }
Is that what you meant? If so, you should know that $private=True
in that signature isn't really setting $private
to anything – it's just providing a default value for the variable $private
. So you can get this output:
sub named(:official($private)=True) {
say $private;
}
named(); # OUTPUT: «True»
named(:official(42)); # OUTPUT: «42»
In any event, I'll send in a PR to the docs repo and try to clarify the named argument examples a bit. Hope you enjoy Raku!
There are a couple of things going on in this short example:
sub named(:official($private)) { "Official business!" if $private }
-------- --------
| |
| > '$private' is the name of this var within the sub
|
> 'official' is the (sigilless) name of this var outside
------------------
|
> ':official($private)' is the
raku Pair 'official => $private'
named :official
----- ---------
| |
| > the raku Pair 'official => True' (so $private ~~ True)
|
> the same as 'named( official => True );'
So when you try this in the repl...
> named :official; #Official business!
> named( official => True ) #Official business! [same thing]
-or-
> named :!official #()
> named( official => False ) #() [same thing]
At first encounter, in this example, raku is quite quirky. Why?
:dothis
but :!notthat
adverbsSo, imho, raku is uniquely cool in that we just have to learn some basic elemental syntax (in this case, the Pair literals) and then they can be applied consistently in many ways to concisely solve quite thorny coding scenarios.
Via pretzel logic I've concluded that:
Or (a tad more likely perhaps... 🤡):
Either way, please read this answer and let me know if it contributes to solving the riddle. TIA. :)
I'm missing something aren't I but what?
Perhaps this is a key for solving the riddle: we're supposed to ask ourselves "What has Keith deliberately missed out of the Q?".
Of course, if this is so, the first thing you've omitted is that it's a riddle. In which case, major kudos! And if it's not an intentional riddle, well, it's still a riddle, so kudos anyway, and let's try solve it!
@codesection's answer points at perhaps the strongest clue. While you didn't write a minimal reproducible example, you did write the sub
definition code, and you did say you'd written $private=False
.
So let's presume you literally wrote that sub
definition and you literally wrote $private=False
.
Furthermore, that:
with
$private=False
invoking 'named' still prints 'Official business!' whereas I thought there should be no output generated.
means there was some output generated in all cases.
Anyhoo, how can all of these things be true at the same time?
These are compile-time errors:
sub named( :official( $private = True ) ) { "Official business!" if $private }
sub named( :official( $private = False ) ) { "Official business!" if $private }
So is this:
$private = False;
unless there was a prior my $private...
.
And this:
sub named( :official( $private ) ) {
$private = True;
"Official business!" if $private
}
named;
yields Cannot assign to a readonly variable or a value
(currently at runtime) because, by default, parameters to routines are readonly.
You also said there was output (ostensibly Official business!
, but perhaps sometimes something else, eg ()
?).
You didn't mention a say
or similar routine for displaying output. How could that be? Let's introduce a say
.
So, putting these things together, and applying pretzel logic, I arrived here:
sub named(:official($private)) { "Official business!" if $private }
my $private;
$private = False;
say named :official; # Official business!
say named :!official; # ()
say named official => False; # ()
say named :official(False); # ()
say named; # ()
An interpretation of this as solving the riddle:
()
is not "no output". So it doesn't contradict your Q narrative.
We've written $private = False
. It has no impact on the code, because of lexical scoping, but we did write it. :)
Am I warm?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With