Rules / Types, classes & roles / domain-specific

IO::Spec::Win32 Reference

Platform specific operations on file and directory paths for Windows

What it is #

Routines #

Signatures are reproduced from the documentation, including their declared return types. A routine listed here is part of the type's published interface; whether Raku++ implements it is a separate question, answered by the examples below.

method basename #

method basename(Str:D $path --> Str:D)

Returns Str:D.

Takes a path as a string and returns a possibly-empty portion after the last slash or backslash:

method canonpath #

method canonpath(Str() $path, :$parent --> Str:D)

Returns Str:D.

Returns a string that is a canonical representation of $path. If :$parent is set to true, will also clean up references to parent directories. NOTE: the routine does not access the filesystem.

method catdir #

method catdir (*@parts --> Str:D)

Returns Str:D.

Concatenates multiple path fragments and returns the canonical representation of the resultant path as a string. The @parts are Str objects and are allowed to contain path separators.

method catfile #

Alias for catdir.

method catpath #

method catpath (Str:D $volume, Str:D $dir, Str:D $file --> Str:D)

Returns Str:D.

Concatenates a path from given volume, a chain of directories, and file. An empty string can be given for any of the three arguments. No attempt to make the path canonical is made. Use canonpath for that purpose.

method devnull #

method devnull(--> Str:D)

Returns Str:D.

Returns the string "nul" representing the "Null device":

method dir-sep #

method dir-sep(--> Str:D)

Returns Str:D.

Returns the string 「\」 representing canonical directory separator character.

method is-absolute #

method is-absolute(Str:D $path --> Bool:D)

Returns Bool:D.

Returns True if the $path starts with a slash ("/") or backslash ("\"), even if they have combining character on them, optionally preceded by a volume:

method join #

method join (Str:D $volume, Str:D $dir, Str:D $file --> Str:D)

Returns Str:D.

Similar to catpath, takes two path fragments and concatenates them, adding or removing a path separator, if necessary, except it will return just $file if both $dir and $file are string '/' or if $dir is the string '.'. The first argument is ignored (it exists to maintain consistent interface with other IO::Spec types for systems that have volumes).

method path #

method path(--> Seq:D)

Returns Seq:D.

Splits the value of %*ENV<PATH> (or %*ENV<Path> if the former is not set) on semicolons (";") and returns a Seq with each of the resultant parts, always adding element "." to the head. Removes all double quotes (") it finds.

method rel2abs #

method rel2abs(Str() $path, $base = $*CWD --> Str:D)

Returns Str:D.

Returns a string representing $path converted to absolute path, based at $base, which defaults to $*CWD. If $base is not an absolute path, it will be made absolute relative to $*CWD, unless $*CWD and $base are the same.

method rootdir #

method rootdir(--> Str:D)

Returns Str:D.

Returns string 「\」, representing root directory.

method split #

method split(IO::Spec::Win32: Cool:D $path)

Creates an IO::Path::Parts for $path. Note: Before Rakudo release 2020.06 this method split the given $path into "volume", "dirname", and "basename" and returned the result as a List of three Pairs, in that order.

method splitdir #

method splitdir(Cool:D $path --> List:D)

Returns List:D.

Splits the given $path on slashes and backslashes.

method splitpath #

method splitpath(Cool:D $path, :$nofile --> List:D)

Returns List:D.

Splits the given $path into a list of 3 strings: volume, dirname, and file. The volume is always an empty string, returned for API compatibility with other IO::Spec types. If :$nofile named argument is set to True, the content of the file string is undefined and should be ignored; this is a means to get a performance boost, as implementations may use faster code path when file is not needed.

method tmpdir #

method tmpdir(--> IO::Path:D)

Returns IO::Path:D.

Attempts to locate a system's temporary directory by checking several typical directories and environment variables. Uses current directory if no suitable directories are found.

Examples, run three ways #

Every example below comes from the official documentation, together with the output that documentation asserts. Each was then executed by Rakudo and by Raku++ when this page was built. Where the three agree, one result is shown; where they do not, all three are — because which of them is wrong is exactly the information worth having.

1 all-differ · 1 doc-drift · 2 no-output · 17 ok · 2 rakupp-differs

class IO::Spec::Win32 is IO::Spec::Unix { }

Not executed: the documentation states no expected output for this example.

IO::Spec::Win32.basename("foo/bar/") .raku.say; # OUTPUT: «""␤»
IO::Spec::Win32.basename("foo/bar\\").raku.say; # OUTPUT: «""␤»
IO::Spec::Win32.basename("foo/bar/.").raku.say; # OUTPUT: «"."␤»
IO::Spec::Win32.basename("foo/bar")  .raku.say; # OUTPUT: «"bar"␤»
Output
""
""
"."
"bar"

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.canonpath("C:/foo//../bar/../ber").say;
# OUTPUT: «C:\foo\..\bar\..\ber␤»
Output
C:\foo\..\bar\..\ber

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.canonpath("C:/foo///./../bar/../ber").say;
# OUTPUT: «C:\foo\..\bar\..\ber␤»
Output
C:\foo\..\bar\..\ber

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.canonpath("C:/foo///./../bar/../ber", :parent).say;
# OUTPUT: «C:\ber␤»
Output
C:\ber

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.catdir(<foo/bar ber raku>).say;
# OUTPUT: «foo\bar\ber\raku␤»
Output
foo\bar\ber\raku

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.catpath('C:', '/some/dir', 'foo.txt').say;
# OUTPUT: «C:/some/dir\foo.txt␤»
Output
C:/some/dir\foo.txt

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.catpath('C:', '/some/dir', '').say;
# OUTPUT: «C:/some/dir␤»
Output
C:/some/dir

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.catpath('', '/some/dir', 'foo.txt').say;
# OUTPUT: «/some/dir\foo.txt␤»
Output
/some/dir\foo.txt

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.catpath('E:', '', 'foo.txt').say;
# OUTPUT: «E:foo.txt␤»
Output
E:foo.txt

Documentation, Rakudo and Raku++ all agree.

$*SPEC.devnull.IO.spurt: "foo bar baz";

Not executed: the documentation states no expected output for this example.

IO::Spec::Win32.dir-sep.say; # OUTPUT: «\␤»
Output
\

Documentation, Rakudo and Raku++ all agree.

say IO::Spec::Win32.is-absolute: "/foo";        # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: "/\x[308]foo"; # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: 「C:\foo」;      # OUTPUT: «True␤»
say IO::Spec::Win32.is-absolute: "bar";         # OUTPUT: «False␤»
Output
True
True
True
False

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.join('C:', '/some/dir', 'foo.txt').say;
# OUTPUT: «C:/some/dir\and/more␤»
Documentation
C:/some/dir\and/more
Rakudo
C:/some/dir\foo.txt
Raku++
C:/some/dir\foo.txt

Both engines agree; the documentation states something else. Trust the engines.

IO::Spec::Win32.join('C:', '.', 'foo.txt').say;
# OUTPUT: «C:foo.txt␤»
Output
C:foo.txt

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.join('C:', 「\」, '/').say;
# OUTPUT: «C:\␤»
Documentation
C:\
Rakudo
C:\
Raku++
C:

Raku++ disagrees with both the documentation and Rakudo — a defect.

IO::Spec::Win32.join('//server/share', 「\」, '/').say;
# OUTPUT: «//server/share␤»
Output
//server/share

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.join('E:', '', 'foo.txt').say;
# OUTPUT: «E:foo.txt␤»
Output
E:foo.txt

Documentation, Rakudo and Raku++ all agree.

%*ENV<PATH> = 'foo;"bar"/"ber"';
IO::Spec::Win32.path.raku.say; # OUTPUT: «(".", "foo", "bar/ber").Seq␤»
Output
(".", "foo", "bar/ber").Seq

Documentation, Rakudo and Raku++ all agree.

say $*CWD;                                   # OUTPUT: «"C:\Users\camelia".IO␤»

say IO::Spec::Win32.rel2abs: 'foo';          # OUTPUT: «C:\Users\camelia\foo␤»
say IO::Spec::Win32.rel2abs: './';           # OUTPUT: «C:\Users\camelia␤»
say IO::Spec::Win32.rel2abs: 'foo/../../';   # OUTPUT: «C:\Users\camelia\foo\..\..␤»
say IO::Spec::Win32.rel2abs: '/foo/';        # OUTPUT: «C:\foo␤»

say IO::Spec::Win32.rel2abs: 'foo', 'bar';   # OUTPUT: «C:\Users\camelia\bar\foo␤»
say IO::Spec::Win32.rel2abs: './', '/bar';   # OUTPUT: «\bar␤»
say IO::Spec::Win32.rel2abs: '/foo/', 'bar'; # OUTPUT: «C:\foo␤»

say IO::Spec::Win32.rel2abs: 'foo/../../', 'bar';
# OUTPUT: «C:\Users\camelia\bar\foo\..\..␤»
Documentation
"C:\Users\camelia".IO
C:\Users\camelia\foo
C:\Users\camelia
C:\Users\camelia\foo\..\..
C:\foo
C:\Users\camelia\bar\foo
\bar
C:\foo
C:\Users\camelia\bar\foo\..\..
Rakudo
"/private/tmp/typerun-sandbox".IO
\private\tmp\typerun-sandbox\foo
\private\tmp\typerun-sandbox
\private\tmp\typerun-sandbox\foo\..\..
\foo
\private\tmp\typerun-sandbox\bar\foo
\bar
\foo
\private\tmp\typerun-sandbox\bar\foo\..\..
Raku++
"/private/tmp/typerun-sandbox".IO
\private\tmp\typerun-sandbox\foo
\private\tmp\typerun-sandbox
\private\tmp\typerun-sandbox\foo\..\..
\foo
bar\foo
\bar
\foo
bar\foo\..\..

All three differ. Needs a human.

Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.

IO::Spec::Win32.split('C:/foo/bar.txt').raku.say;
# OUTPUT: «IO::Path::Parts.new("C:","/foo","bar.txt")␤»

IO::Spec::Win32.split('/foo/').raku.say;
# OUTPUT: «IO::Path::Parts.new("","/","foo")␤»

IO::Spec::Win32.split('///').raku.say;
# OUTPUT: «IO::Path::Parts.new("","/","\\")␤»

IO::Spec::Win32.split('./').raku.say;
# OUTPUT: «IO::Path::Parts.new("",".",".")␤»

IO::Spec::Win32.split('.').raku.say;
# OUTPUT: «IO::Path::Parts.new("",".",".")␤»

IO::Spec::Win32.split('').raku.say;
# OUTPUT: «IO::Path::Parts.new("","","")␤»
Documentation
IO::Path::Parts.new("C:","/foo","bar.txt")
IO::Path::Parts.new("","/","foo")
IO::Path::Parts.new("","/","\\")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("","","")
Rakudo
IO::Path::Parts.new("C:","/foo","bar.txt")
IO::Path::Parts.new("","/","foo")
IO::Path::Parts.new("","/","\\")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("","","")
Raku++
IO::Path::Parts.new("C:","/foo","bar.txt")
IO::Path::Parts.new("","\\","foo")
IO::Path::Parts.new("","\\","\\")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("",".",".")
IO::Path::Parts.new("","\\","\\")

Raku++ disagrees with both the documentation and Rakudo — a defect.

IO::Spec::Win32.splitdir('C:\foo/bar.txt').raku.say;
# OUTPUT: «("C:", "foo", "bar.txt")␤»

IO::Spec::Win32.splitdir('/foo/').raku.say;
# OUTPUT: «("", "foo", "")␤»

IO::Spec::Win32.splitdir('///').raku.say;
# OUTPUT: «("", "", "", "")␤»

IO::Spec::Win32.splitdir('./').raku.say;
# OUTPUT: «(".", "")␤»

IO::Spec::Win32.splitdir('.').raku.say;
# OUTPUT: «(".",)␤»

IO::Spec::Win32.splitdir('').raku.say;
# OUTPUT: «("",)␤»
Output
("C:", "foo", "bar.txt")
("", "foo", "")
("", "", "", "")
(".", "")
(".",)
("",)

Documentation, Rakudo and Raku++ all agree.

IO::Spec::Win32.splitpath('C:\foo/bar.txt').raku.say;
# OUTPUT: «("C:", "\\foo/", "bar.txt")␤»

IO::Spec::Win32.splitpath('C:\foo/bar.txt', :nofile).raku.say;
# OUTPUT: «("C:", "\\foo/bar.txt", "")␤»

IO::Spec::Win32.splitpath('/foo/').raku.say;
# OUTPUT: «("", "/foo/", "")␤»

IO::Spec::Win32.splitpath('/foo/', :nofile).raku.say;
# OUTPUT: «("", "/foo/", "")␤»

IO::Spec::Win32.splitpath('///').raku.say;
# OUTPUT: «("", "///", "")␤»

IO::Spec::Win32.splitpath('./').raku.say;
# OUTPUT: «("", "./", "")␤»

IO::Spec::Win32.splitpath('.').raku.say;
# OUTPUT: «("", "", ".")␤»

IO::Spec::Win32.splitpath('').raku.say;
# OUTPUT: «("", "", "")␤»
Output
("C:", "\\foo/", "bar.txt")
("C:", "\\foo/bar.txt", "")
("", "/foo/", "")
("", "/foo/", "")
("", "///", "")
("", "./", "")
("", "", ".")
("", "", "")

Documentation, Rakudo and Raku++ all agree.