I'd like to do the following in raku on windows
raku -n -e ".say if /mydatabegin/;" *.file
Failed to open file C:\..\*.file: Invalid argument
The glob isn't interpreted as a glob. I assume that's because windows requires your programs to do the globbing yourself? So is there a pre-processing directive or function or even a switch I might have missed or redirect or something that allows the glob to be expanded while keeping the simplicity of the -n (or -p) and -e switches?
Obviously, I can change it to a full program by removing the -n (or -p), just using -e to specify a main, and loop on the glob results. But I really like -n.
PS. I'm literally just learning raku, and was surprised this didn't work out of the box. So examples of full programs with easy syntax work also. But I really like -n..
Edit: re @chenyf
raku -e ".say for $*ARGFILES" *.file
Same error. Related:
raku -e ".say for $*ARGFILES.lines" *.file
Same error.
raku -e "use IO::Glob; .say for glob('*.file')"
Worked as expected! Expanding:
raku -e "use IO::Glob; .say for glob('*.file').lines"
No such method 'lines' for invocant of type 'IO::Glob'
Getting closer - perhaps expanding on this is a good enough workaround. But returning to one line glory attempts:
raku -e "use IO::Glob; .say for glob($*ARGFILES)" test.file
Cannot resolve caller glob(IO::ArgFiles:D); none of these signatures match.
Ok - let's retreat back to the safety of strings:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" test.file
Yes! SO..:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str).lines" test.file
No such method 'lines' for invocant of type 'IO::Glob'
I clearly need to read more of the manual. But let's retreat a little and see if my use case works:
raku -e "use IO::Glob; .say for glob($*ARGFILES.Str)" *.file
Failed to open file C:\..\*.file: Invalid argument
The same error I started off with. Could this just be a raku on windows error?
Edit:
raku -MIO::Glob -e "my @files = (map { glob($_).dir }, @*ARGS).flat; for @files -> $file { say $_ for $file.lines }" *file *file2 *5
I have three sets of files. I can almost live with this solution - except for some reason the lines are being printed with "s
Any ideas on shortening, and getting rid of the quotes?
EDIT Working around the auto-globbing of the $*ARGFILES variable:
raku -MIO::Glob -n -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say" *.file *.file2
This has the advantage of still looking like the original one liner; it uses -n! It just had to do the globbing that seems to be a bug when $*ARGFILES is created.
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob($_) }, @*ARGS).flat }; .say for $*ARGFILES.lines" *.file *.file2
Converting to $*ARGFILES.lines above shows that $*ARGFILES gets its values from @*ARGS dynamically.
EDIT
lastly, it turns out the glob function doesn't work with directories, at least on windows (the documentation has an example that simply doesn't work).
#Example from https://github.com/zostay/raku-IO-Glob
for glob("src/core/*.pm") -> $file { say ~$file }
#mine that doesn't work
raku -MIO::Glob -e "for glob('..\*.file') -> $file { say ~$file }"
#mine that does work.
raku -MIO::Glob -e "for glob('*.file').dir('..') -> $file { say ~$file }"
#And therefore the final modification of the script above:
raku -MIO::Glob -e "BEGIN { @*ARGS = (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS).flat }; .say for $*ARGFILES.lines" ..\*.file
The general answer - Its not a bug. Windows programs have to deal with their own globbing if they want it. Making it work in the raku executable makes sense to me; it removes platform specific surprises, and makes one-liners easier.
But others didn't see it that way, and there is an easy enough solution - create your own module so that the code can remain consistent and be called relatively simply.
Here's a module for starters. There is room to add things like
The module:
unit module CLGlob:ver<1.0>:auth<pureabsolute>;
use IO::Glob;
@*ARGS = map { .Str }, (map { glob(.IO.basename).dir(.IO.dirname) }, @*ARGS ).flat;
Note: the expression in the second map can be simplified when the glob function works for windows with directories.
Note: I convert each element to .Str to make @*ARGS consistent. The $*ARGFILES worked without doing that so some processing can be saved if you'll never look at the @*ARGS again.
Finally, the end result:
raku -MCLGlob -ne ".say" ..\*.file ..\*.file2
Yay.