A valid Match object is not empty or undefined in my opinion:
say Match.new(:orig("20230213112803"), :from(4), :pos(6)).elems; # 0
say Match.new(:orig("20230213112803"), :from(4), :pos(6)).chars; # 2
say Match.new(:orig("20230213112803"), :from(4), :pos(6)).defined; # True
but the following pointy block with a Match
object in a for
loop outputs Nil
:
for Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m {
say ~$m
}
# OUTPUT: Nil
But the given
statement outputs what I expected:
given Match.new(:orig("20230213112803"), :from(4), :pos(6)) -> $m {
say ~$m
}
# OUTPUT: 02
Isn't something empty or undefined that prevents a for
loop from executing?
for "a" -> $m { say $m } # a
for [] -> $m { say $m } # Nil
for {} -> $m { say $m } # Nil
TL;DR given
will always treat its argument as one thing (an object). In contrast, for
is a looping construct, and may ask its argument to .list
its elements so it can usefully loop. It does so in your example, and the Match
object contains no elements, so the for
doesn't call the block at all.
given foo
(or given foo, bar
)given
just makes its argument(s) the topic ("it") and calls the associated statement or block (passing in the topic). End of story.
for foo, bar
for foo, bar
just makes each of its arguments the topic in turn (and calls the associated statement/block). Again, end of story.
for foo
If for
only has one argument, and that argument is not explicitly marked as singular (by prefixing it with $
), then for
calls .list
on that argument and, for each value in the returned list it sets that to "it" and calls the associated statement/block, one-by-one. That's your scenario. Again, end of story.
Except this clearly confused you (and Liz), so there needs to be a bit more to my answer!
Like an array or a hash, a Capture
(and thus Match
) object may contain zero or more elements. In all these cases the object itself is not an element.
A Rakoon is not surprised when for [] { ... }
does nothing, because the []
very obviously contains no elements, and it would be kinda silly, not to mention confusing, for the array to return itself as if it were an element of itself.
What about for Match.new { ... }
? It also does nothing, and it's perhaps obvious why not -- because it also contains no elements.
But what about your example? Well, again, it does nothing, and again, it's because it contains no elements.
But "what?!?" you say! Surely the match object is itself useful data? Why doesn't the for
treat it like it would, say, for 42 { ... }
? Well, because if you absolutely want that, then write given 42 { ... }
instead. If you use for
, then expect Raku to seek out a list meaning for its argument(s), not a singular meaning, and that means calling .list
on its argument in the scenario in your question.
Then what are a Match
object's elements? They are its child Match
objects, if any. There may be positional ones (which you can access with, for example, match-object[...]
, or .list
), and named ones (which you can access with, for example, match-object{...}
or .hash
).