How the different newline characters are handled, and how to change the behavior
Different operating systems use different characters, or combinations of them, to represent the transition to a new line. Every language has its own set of rules to handle this. Raku has the following ones:
\n
in a string literal means Unicode codepoint 10.
The default nl-out that is appended to a string by say is also \n
.
On output, when on Windows, the encoder will by default transform a \n
into a \r\n
when it's going to a file, process, or terminal (it won't do this on a socket, however).
On input, on any platform, the decoder will by default normalize \r\n
into \n
for input from a file, process, or terminal (again, not socket).
These above two points together mean that you can - socket programming aside - expect to never see a \r\n
inside of your program (this is how things work in numerous other languages too).
The :$translate-nl
named parameter exists in various places to control this transformation, for instance, in Proc::Async.new
and Proc::Async.Supply
.
A \n
in the regex language is logical, and will match a \r\n
.
You can change the default behavior for a particular handle by setting the :nl-out
attribute when you create that handle.
my = open(IO::Special.new('<STDOUT>'), :nl-out("\\\n\r"));.say: 1; # OUTPUT: «1».say: 1; # OUTPUT: «1\␍»
In this example, where we are replicating standard output to a new handle by using IO::Special, we are appending a \
to the end of the string, followed by a newline 
and a carriage return ␍
; everything we print to that handle will get those characters at the end of the line, as shown.
In regular expressions, \n
is defined in terms of the Unicode definition of logical newline. It will match .
and also \v
, as well as any class that includes whitespace.