Skip to content

Commit b9e692e

Browse files
authored
[io grant] Document new IO::Path.extension
- Now has a means to specify the number of parts in the wanted extension - Now has a means to replace an extension with a new one, optionally joining it to the filename with a non-'.' joiner Rakudo impl. rakudo/rakudo@b1e7a01f87 Tests: Raku/roast@b23e53eb79
1 parent bdb7ab4 commit b9e692e

File tree

1 file changed

+63
-6
lines changed

1 file changed

+63
-6
lines changed

doc/Type/IO/Path.pod6

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,71 @@ the file relative to its directory.
5757
5858
say IO::Path.new("docs/README.pod").basename; # OUTPUT: «README.pod␤»
5959
60-
6160
=head2 method extension
6261
63-
method extension(IO::Path:D:)
64-
65-
Returns the extension (if any) of the path object.
66-
67-
say IO::Path.new("docs/README.pod").extension; # OUTPUT: «pod␤»
62+
Defined as:
63+
64+
multi extension(IO::Path:D --> Str:D)
65+
multi extension(IO::Path:D Int :$parts --> Str:D)
66+
multi extension(IO::Path:D Range :$parts --> Str:D)
67+
multi extension(IO::Path:D Str $subst, Int :$parts, Str :$joiner --> IO::Path:D)
68+
multi extension(IO::Path:D Str $subst, Range :$parts, Str :$joiner -->
69+
IO::Path:D)
70+
71+
Returns the extension consisting of C<$parts> parts (defaults to C<1>),
72+
where a "part" is defined
73+
as a dot followed by possibly-empty string up to the end of the string, or
74+
previous part. That is C<"foo.tar.gz"> has an extension of two parts: first part
75+
is C<"gz"> and second part is C<"tar"> and calling
76+
C<"foo.tar.gz".IO.extension: :2parts> gives C<"tar.gz">. If an extension with
77+
the specified number of C<$parts> is not found, returns an empty string.
78+
79+
C<$parts> can be a L«C<Range>|/type/Range», specifying the minimum number of
80+
parts and maximum number of parts the extension should have. The routine will
81+
attempt to much the most parts it can. If C<$parts> range's endpoints that are
82+
smaller than C<0> they'll be treated as C<0>; implementations may treat
83+
endpoints larger than C<2⁶³-1> as C<2⁶³-1>. Ranges with C<NaN> or
84+
L«C<Str>|/type/Str» endpoints will cause an exception to be thrown.
85+
86+
If C<$subst> is provided, the extension will be instead replaced with C<$subst>
87+
and a new C<IO::Path> object will be returned. It will be joined to the file's
88+
name with C<$joiner>, which defaults to an empty string when C<$subst> is
89+
an empty string and to C<"."> when C<$subst> is not empty. B<Note:> if as
90+
the result of replacement the L«C<basename>|/routine/basename» of the path
91+
ends up being empty, it will be assumed to be C<.> (a single dot).
92+
93+
# Getting an extension:
94+
say "foo.tar.gz".IO.extension2; # OUTPUT: «gz␤»
95+
say "foo.tar.gz".IO.extension2: :2parts; # OUTPUT: «tar.gz␤»
96+
say "foo.tar.gz".IO.extension2: :parts(^5); # OUTPUT: «tar.gz␤»
97+
say "foo.tar.gz".IO.extension2: :parts(0..1); # OUTPUT: «gz␤»
98+
99+
# Replacing an extension
100+
say "foo.tar.gz".IO.extension2: ''; # OUTPUT: «"foo.tar".IO␤»
101+
say "foo.tar.gz".IO.extension2: 'ZIP'; # OUTPUT: «"foo.tar.ZIP".IO␤»
102+
say "foo.tar.gz".IO.extension2: 'ZIP', :0parts; # OUTPUT: «"foo.tar.gz.ZIP".IO␤»
103+
say "foo.tar.gz".IO.extension2: 'ZIP', :2parts; # OUTPUT: «"foo.ZIP".IO␤»
104+
say "foo.tar.gz".IO.extension2: 'ZIP', :parts(^5); # OUTPUT: «"foo.ZIP".IO␤»
105+
106+
# Replacing an extension using non-standard joiner:
107+
say "foo.tar.gz".IO.extension2: '', :joiner<_>; # OUTPUT: «"foo.tar_".IO␤»
108+
say "foo.tar.gz".IO.extension2: 'ZIP', :joiner<_>; # OUTPUT: «"foo.tar_ZIP".IO␤»
109+
say "foo.tar.gz".IO.extension2: 'ZIP', :joiner<_>, :2parts; # OUTPUT: «"foo_ZIP".IO␤»
110+
say "foo.tar.gz".IO.extension2: 'ZIP', :joiner<_>, :parts(^5); # OUTPUT: «"foo_ZIP".IO␤»
111+
112+
# EDGE CASES:
113+
# There is no 5-part extension, so returned value is an empty string
114+
say "foo.tar.gz".IO.extension2: :5parts; # OUTPUT: «␤»
115+
# There is no 5-part extension, so we replaced nothing:
116+
say "foo.tar.gz".IO.extension2: 'ZIP', :5parts; # OUTPUT: «"foo.tar.gz".IO␤»
117+
# Replacing a 0-part extension, is just appending:
118+
say "foo.tar.gz".IO.extension2: 'ZIP', :0parts; # OUTPUT: «"foo.tar.gz.ZIP".IO␤»
119+
# A replace 1 part of the extension, using '.' joiner
120+
say "...".IO.extension2: 'tar'; # OUTPUT: «"....tar".IO␤»
121+
# A replace 1 part of the extension, using empty string joiner
122+
say "...".IO.extension2: 'tar', :joiner(''); # OUTPUT: «"...tar".IO␤»
123+
# Remove 1-part extension; results in empty basename, so result is ".".IO
124+
say ".".IO.extension2: ''; # OUTPUT: «".".IO␤»
68125
69126
=head2 method dirname
70127

0 commit comments

Comments
 (0)