It is really the combination of CONTROL and CX::Succeed that are preventing the default behaviour of last.
All of the flow control functions are implemented in terms of exceptions.
Rather than lump them in with regular exceptions in CATCH, there is a special handler just for them named CONTROL.
Both CATCH and CONTROL can be thought of as special forms of given.
The two main differences being that the topic is set to the exception, and that something special happens if there was a CX::Succeed.
If there is a CX::Succeed then that indicates the exception or flow-control was successfully handled, and that no further processing needs to happen.
There are two ways to get CX::Succeed to happen inside of CONTROL.
default block
when block
(Technically I think that just plain succeed should also work, but it doesn't seem to.)
If you are in one of those blocks, and you want the processing to actually continue, you can use proceed (CX::Proceed).
loop {
once {
CX::Vaya.new( message => "I messed up!" ).throw;
}
last;
CONTROL {
default {
.^name.say;
proceed if CX::Last;
}
}
}
It is much better to just use a when block that captures exactly what you want to handle specially.
(Note that a postfix when does not throw CX::Succeed, so normal processing would continue in that case.)
default is a block prefix. Meaning it always must be followed by a block.
Adding just : to the end of an identifier is only used to create a label, and on method calls to remove the parentheses.
So default: does absolutely nothing here.
Also once is not a block prefix. It is a statement prefix. (It just so happens that a block can be treated as a statement.)
There is no reason to add a block there unless you are going to write more than one statement inside of it.
loop {
once CX::Vaya.new( message => "I messed up!" ).throw;
last;
CONTROL {
when CX::Vaya {
.^name.say;
}
}
}