Skip to content

Instantly share code, notes, and snippets.

@robin-a-meade
Last active April 17, 2022 21:48
Show Gist options
  • Save robin-a-meade/1b2c9d6a1dc3c5d74ba57c5b95c8ed54 to your computer and use it in GitHub Desktop.
Save robin-a-meade/1b2c9d6a1dc3c5d74ba57c5b95c8ed54 to your computer and use it in GitHub Desktop.
perl io layers and -CSDA demo
#!/bin/perl
#!/bin/perl -CSDA # Try this variation
use v5.16.3;
use warnings;
use File::Temp qw(tempfile tempdir);
my @layers;
print 'tmp layers: ';
my $tmp = tempfile();
binmode($tmp, ":utf8" ); # See the effect of this line
#binmode($tmp);
binmode($tmp, ":raw"); # Equivalent
# ":raw" is the default. It "removes any layers that would interfere with binary data"
# - https://docstore.mik.ua/orelly/perl4/cook/ch08_12.htm
@layers = PerlIO::get_layers($tmp);
say "@layers";
say 'fh layers: ';
my $dir = tempdir( CLEANUP => 0 );
my $filepath = "$dir/out.txt";
say $filepath;
open(my $fh, '>', $filepath) or die "Unable to open '$filepath': $!";
# Try these variations:
#open(my $fh, '>:encoding(UTF-8)', $filepath) or die "Unable to open '$filepath': $!";
#open(my $fh, '>:raw', $filepath) or die "Unable to open '$filepath': $!";
binmode($fh, ":crlf" ); # See the effect of this line
# Note: ":crlf" is automatically added on Windows
# You'd need to specify ":crlf" only in the unusual situation of
# dealing with data with crlf line endings on a unix-like platform
# See: https://docstore.mik.ua/orelly/perl4/cook/ch08_12.htm
say $fh "A"; # Will have crlf line ending if the ":crlf" io layer was added above
my $fd = fileno $fh;
say readlink("/proc/$$/fd/$fd"); # Demo of how to find file name from $fh
@layers = PerlIO::get_layers($fh);
say "@layers";
print 'STDIN layers: ';
@layers = PerlIO::get_layers(STDIN);
say "@layers";
print 'STDOUT layers: ';
@layers = PerlIO::get_layers(STDOUT);
say "@layers";
print 'STDERR layers: ';
@layers = PerlIO::get_layers(STDERR);
say "@layers";
# Determine current locale
# https://stackoverflow.com/a/15274055
use POSIX qw(setlocale locale_h LC_ALL);
say setlocale(LC_ALL); # Is it proper to call with LC_ALL? ¯\_(ツ)_/¯ Seems to work.
# This is probably a better way to inspect the codeset of current locale:
# Determine codeset of current locale
# https://unix.stackexchange.com/a/210626
# Accepted answer refers to:
# https://stackoverflow.com/a/29871568
use I18N::Langinfo qw(langinfo CODESET);
say langinfo(CODESET());
# So, this is how you could require a UTF-8 locale:
die 'This script requires UTF-8 locale' unless langinfo(CODESET()) eq 'UTF-8';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment