You have read the Exercise text first?
We start with the file name, as a constant (without a sigil):
constant CONF_FILE = ( $*HOME.add: '.rashrc' ).Str;
See docs.raku.org/routine/constant
for more information about constant
.
Then we call «read-conf» instead of the «do-allow "more";»-line:
read-conf;
And finally we define «read-conf»:
sub read-conf
{
return unless CONF_FILE.IO.r;
for CONF_FILE.IO.lines
{
.say;
}
}
Check that it works, without the «.rashrc» file.
Add the «.rashrc» file, and see that the allow-lines are displayed:
$ raku rash-conf
allow more
allow top
rash: Enter «exit» to exit
>
Then we can swap the dummy say
line with a copy of the when
line:
sub read-conf
{
return unless CONF_FILE.IO.r;
for CONF_FILE.IO.lines
{
when /^allow\s+(.*)/ { do-allow $0.Str; }
}
}
You do remember that the trailing
.Str
is extremely important here, as $0
is a match
object and not a string.
The complete program (based on «rash-pwd»):
File: rash-conf
use Linenoise;
constant HIST_FILE = ( $*HOME.add: '.rash-hist' ).Str;
constant HIST_LEN = 25;
constant CONF_FILE = ( $*HOME.add: '.rashrc' ).Str;
linenoiseHistoryLoad(HIST_FILE);
linenoiseHistorySetMaxLen(HIST_LEN);
my @commands = <allow cd exit help pwd run version>;
my %allow;
read-conf;
linenoiseSetCompletionCallback(-> $line, $c
{
for @commands.grep(/^ $line /).sort -> $cmd
{
linenoiseAddCompletion($c, $cmd);
}
});
say 'rash: Enter «exit» to exit';
while (my $line = linenoise '> ').defined
{
linenoiseHistoryAdd($line);
given $line
{
when /^allow\s+(.*)/ { do-allow $0; }
when /^cd\s+(\S+)/ { do-chdir $0; }
when "exit" { last; }
when "help" { say "Legal commands: { @commands }" }
when "pwd" { say $*CWD.Str; }
when /^run\s+(.*)/ { do-run $0; }
when "version" { say "Version 0.11"; }
default
{
my ($cmd, $arg) = $line.split(/\s/, 2);
%allow{$cmd}
?? do-run $line
!! say "Unknown command: \"$_\" (use \"help\" for a list of commands)";
}
}
}
linenoiseHistorySave(HIST_FILE);
sub do-run ($line)
{
my ($cmd, @args) = $line.words;
my $res = @args
?? run $cmd, @args
!! run $cmd;
if ! $res.pid
{
say "$cmd: command not found";
}
elsif $res.exitcode
{
say "$cmd: exit with code { $res.exitcode }";
}
}
sub do-chdir ($dir)
{
say "cd: $dir: No such file or directory" unless chdir $dir;
}
sub do-allow ($cmd)
{
@commands.push($cmd);
%allow{$cmd} = True;
}
sub read-conf
{
return unless CONF_FILE.IO.r;
for CONF_FILE.IO.lines
{
when /^allow\s+(.*)/ { do-allow $0.Str; }
}
}