Slipping in a Config File
I wanted to add a config file to META6::bin
without adding another dependency and without adding a grammar or other forms of fancy (and therefore time consuming) parsers. As it turns out, .split
and friends are more then enough to get the job done.
# META6::bin config file general.timeout = 60 git.timeout = 120 git.protocol = https
That’s how the file should look like and I wanted a multidim Hash in the end to query values like %config<git><timeout>
.
our sub read-cfg($path) is export(:HELPER) { use Slippy::Semilist; return unless $path.IO.e; my %h; slurp($path).lines\ ».chomp\ .grep(!*.starts-with('#'))\ .grep(*.chars)\ ».split(/\s* '=' \s*/)\ .flat.map(-> $k, $v { %h{||$k.split('.').cache} = $v }); %h }
We slurp
in the whole file and process it line by line. All newlines are removed and any line that starts with a #
or is empty is skipped. We separate values and keys by =
and use a Semilist Slip to build the multidim Hash. Abusing a .map
that doesn’t return values is a bit smelly but keeps all operations in order.
A Semilist is the thing you can find in %hash{1;2;3}
(same for arrays) to express multi-dimentionallity. Just using a normal list wont cut it because a list is a valid key for a Hash
.
I had Rakudo::Slippy::Semilist
laying around for quite some time but never really used it much because it’s cheating by using nqp-ops to get some decent speed. As it turned out it’s not really the operations on a Hash as the circumfix:<{ }>-operator
itself that is causing a 20x speed drop. By calling .EXISTS-KEY
and .BIND-KEY
directly the speed hit shrinks down to 7% over a nqp-implementation.
It’s one of those cases where things fall into place with Perl 6. Being able to define my own operator in conjunction with ».
allows to keep the code flowing in the order of thoughs instead of breaking it up into nested loops.
-
April 18, 2017 at 10:072017.16 IO Hits The Road | Weekly changes in and around Perl 6