The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
<html><head><title>Parse::Path</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" >
</head>
<body class='pod'>
<!--
  generated by Pod::Simple::HTML v3.22,
  using Pod::Simple::PullParser v3.22,
  under Perl v5.014002 at Thu Sep 12 01:19:04 2013 GMT.

 If you want to change this HTML document, you probably shouldn't do that
   by changing it directly.  Instead, see about changing the calling options
   to Pod::Simple::HTML, and/or subclassing Pod::Simple::HTML,
   then reconverting this document from the Pod source.
   When in doubt, email the author of Pod::Simple::HTML for advice.
   See 'perldoc Pod::Simple::HTML' for more info.

-->

<!-- start doc -->
<a name='___top' class='dummyTopAnchor' ></a>

<h1><a class='u'
name="NAME"
>NAME</a></h1>

<p>Parse::Path - Parser for paths</p>

<h1><a class='u'
name="SYNOPSIS"
>SYNOPSIS</a></h1>

<pre>    use v5.10;
    use Parse::Path;
 
    my $path = Parse::Path-&#62;new(
       path  =&#62; &#39;gophers[0].food.count&#39;,
       style =&#62; &#39;DZIL&#39;,  # default
    );
 
    my $step = $path-&#62;shift;  # { key =&#62; &#39;count&#39;, ... }
    say $path-&#62;as_string;
    $path-&#62;push($path, &#39;[2]&#39;);
 
    foreach my $p (@$path) {
       say sprintf(&#39;%-6s %s --&#62; %s&#39;, @$p{qw(type step key)});
    }</pre>

<h1><a class='u'
name="DESCRIPTION"
>DESCRIPTION</a></h1>

<p>Parse::Path is, well, a parser for paths. File paths, object paths, URLs... A path is whatever string that can be translated into hash/array keys. Unlike modules like <a href="http://search.cpan.org/perldoc?File%3A%3ASpec" class="podlinkpod"
>File::Spec</a> or <a href="http://search.cpan.org/perldoc?File%3A%3ABasename" class="podlinkpod"
>File::Basename</a>, which are designed for interacting with file systems paths in a portable manner, Parse::Path is designed for interacting with <i>any</i> path, filesystem or otherwise, at the lowest level possible.</p>

<p>Paths are split out into steps. Internally, these are stored as &#34;step hashes&#34;. However, there is some exposure to these hashes as both input and output, so we&#39;ll describe them here:</p>

<pre>    {
       type =&#62; &#39;HASH&#39;,       # must be either HASH or ARRAY
       key  =&#62; &#39;foo bar&#39;,    # as it would be represented as a key
       step =&#62; &#39;&#34;foo bar&#34;&#39;,  # as it would be represented in a path
       pos  =&#62; &#39;X+1&#39;,        # used to determine depth
    }</pre>

<p>For the purposes of this manual, a &#34;step&#34; is usually referring to a step hash, unless specified.</p>

<h1><a class='u'
name="CONSTRUCTOR"
>CONSTRUCTOR</a></h1>

<pre>    my $path = Parse::Path-&#62;new(
       path  =&#62; $path,   # required
       style =&#62; &#39;DZIL&#39;,  # default
    );</pre>

<p>Creates a new path object. Parse::Path is really just a dispatcher to other Parse::Path modules, but it serves as a common API for all of them.</p>

<p>Accepts the following arguments:</p>

<h2><a class='u'
name="path"
>path</a></h2>

<pre>    path =&#62; &#39;gophers[0].food.count&#39;</pre>

<p>String used to create path. Can also be another Parse::Path object, a step, an array of step hashes, an array of paths, or whatever makes sense.</p>

<p>This parameter is required.</p>

<h2><a class='u'
name="style"
>style</a></h2>

<pre>    style =&#62; &#39;File::Unix&#39;
    style =&#62; &#39;=MyApp::Parse::Path::Foobar&#39;</pre>

<p>Class used to create the new path object. With a <code>=</code> prefix, it will use that as the full class. Otherwise, the class will be intepreted as <code>Parse::Path::$class</code>.</p>

<p>Default is <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3ADZIL" class="podlinkpod"
>DZIL</a>.</p>

<h2><a class='u'
name="auto_normalize"
>auto_normalize</a></h2>

<pre>    auto_normalize =&#62; 1
 
    my $will_normalize = $path-&#62;auto_normalize;
    $path-&#62;auto_normalize(1);</pre>

<p>If on, calls <a href="#normalize" class="podlinkpod"
>&#34;normalize&#34;</a> after any new step has been added (ie: <a href="#CONSTRUCTOR" class="podlinkpod"
>new</a>, <a href="#unshift" class="podlinkpod"
>&#34;unshift&#34;</a>, <a href="#push" class="podlinkpod"
>&#34;push&#34;</a>, <a href="#splice" class="podlinkpod"
>&#34;splice&#34;</a>).</p>

<p>Default is off. This attribute is read-write.</p>

<h2><a class='u'
name="auto_cleanup"
>auto_cleanup</a></h2>

<pre>    auto_cleanup =&#62; 1
 
    my $will_cleanup = $path-&#62;auto_cleanup;
    $path-&#62;auto_cleanup(1);</pre>

<p>If on, calls <a href="#cleanup" class="podlinkpod"
>&#34;cleanup&#34;</a> after any new step has been added (ie: <a href="#CONSTRUCTOR" class="podlinkpod"
>new</a>, <a href="#unshift" class="podlinkpod"
>&#34;unshift&#34;</a>, <a href="#push" class="podlinkpod"
>&#34;push&#34;</a>, <a href="#splice" class="podlinkpod"
>&#34;splice&#34;</a>).</p>

<p>Default is off. This attribute is read-write.</p>

<h1><a class='u'
name="METHODS"
>METHODS</a></h1>

<h2><a class='u'
name="step_count"
>step_count</a></h2>

<pre>    my $count = $path-&#62;step_count;</pre>

<p>Returns the number of steps in the path. Unlike <a href="#depth" class="podlinkpod"
>&#34;depth&#34;</a>, negative-seeking steps (like <code>..</code> for most file-based paths) will not lower the step count.</p>

<h2><a class='u'
name="depth"
>depth</a></h2>

<pre>    my $depth = $path-&#62;depth;</pre>

<p>Returns path depth. In most cases, this is the number of steps to the path, a la <a href="#step_count" class="podlinkpod"
>&#34;step_count&#34;</a>. However, relative paths might make this lower, or even negative. For example:</p>

<pre>    my $path = Parse::Path-&#62;new(
       path =&#62; &#39;../../../foo/bar.txt&#39;,
       path_style =&#62; &#39;File::Unix&#39;,
    );
 
    say $path-&#62;step_count;  # 5
    say $path-&#62;depth;       # -1</pre>

<p>Despite the similarity to the pos value of a step hash, this method doesn&#39;t tell you whether it&#39;s relative or absolute. Use <a href="#is_absolute" class="podlinkpod"
>&#34;is_absolute&#34;</a> for that.</p>

<h2><a class='u'
name="is_absolute"
>is_absolute</a></h2>

<pre>    my $is_absolute = $path-&#62;is_absolute;</pre>

<p>Returns a true value if this path is absolute. Hint: most paths are relative. For example, if the following paths were <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3AFile%3A%3AUnix" class="podlinkpod"
>File::Unix</a> paths:</p>

<pre>    foo/bar.txt        # relative
    ../bar.txt         # relative
    bar.txt            # relative
    /home/foo/bar.txt  # absolute
    /home/../bar.txt   # absolute (even prior to cleanup)</pre>

<h2><a class='u'
name="as_string"
>as_string</a></h2>

<pre>    my $path_str = $path-&#62;as_string;</pre>

<p>Returns the string form of the path. This involves taking the individual step strings of the path and placing the delimiters in the right place.</p>

<h2><a class='u'
name="as_array"
>as_array</a></h2>

<pre>    my $step_hashes = $path-&#62;as_array;</pre>

<p>Returns the full path as an arrayref of step hashes. The steps are cloned for integrity. If you want a simplier representation of the path, consider <a href="#as_string" class="podlinkpod"
>&#34;as_string&#34;</a>.</p>

<h2><a class='u'
name="shift"
>shift</a></h2>

<pre>    my $step_hash = $path-&#62;shift;</pre>

<p>Works just like the Perl version. Removes a step from the beginning of the path and returns it. The step is cloned for integrity.</p>

<h2><a class='u'
name="pop"
>pop</a></h2>

<pre>    my $step_hash = $path-&#62;pop;</pre>

<p>Works just like the Perl version. Removes a step from the end of the path and returns it. The step is cloned for integrity.</p>

<h2><a class='u'
name="unshift"
>unshift</a></h2>

<pre>    my $count = $path-&#62;unshift($step_or_path);</pre>

<p>Works just like the Perl version. Adds a step (or other path-like thingy) to the beginning of the path and returns the number of new steps prepended. Will also call <a href="#cleanup" class="podlinkpod"
>&#34;cleanup&#34;</a> afterwards, if <a href="#auto_cleanup" class="podlinkpod"
>&#34;auto_cleanup&#34;</a> is enabled.</p>

<h2><a class='u'
name="push"
>push</a></h2>

<pre>    my $count = $path-&#62;push($step_or_path);</pre>

<p>Works just like the Perl version. Adds a step (or other path-like thingy) to the end of the path and returns the number of new steps appended. Will also call <a href="#cleanup" class="podlinkpod"
>&#34;cleanup&#34;</a> afterwards, if <a href="#auto_cleanup" class="podlinkpod"
>&#34;auto_cleanup&#34;</a> is enabled.</p>

<h2><a class='u'
name="splice"
>splice</a></h2>

<pre>    my @step_hashes = $path-&#62;splice($offset, $length, $step_or_path);
    my @step_hashes = $path-&#62;splice($offset, $length);
    my @step_hashes = $path-&#62;splice($offset);
 
    my $last_step_hash = $path-&#62;splice($offset);</pre>

<p>Works just like the Perl version. Removes elements designated by the offset and length, and replaces them with the new step/path. The steps are cloned for integrity. Returns the steps removed in list context, or the last step removed in scalar context. Will also call <a href="#cleanup" class="podlinkpod"
>&#34;cleanup&#34;</a> afterwards, if <a href="#auto_cleanup" class="podlinkpod"
>&#34;auto_cleanup&#34;</a> is enabled.</p>

<h2><a class='u'
name="clear"
>clear</a></h2>

<pre>    $path-&#62;clear;</pre>

<p>Clears out the path.</p>

<p>Returns itself for chaining.</p>

<h2><a class='u'
name="replace"
>replace</a></h2>

<pre>    $path-&#62;replace;</pre>

<p>Replaces the path with a new one. Basically just sugar for <a href="#clear" class="podlinkpod"
>&#34;clear&#34;</a> + <a href="#push" class="podlinkpod"
>&#34;push&#34;</a>. Unlike the argument form of <a href="#clone" class="podlinkpod"
>&#34;clone&#34;</a>, this retains the same object and just replaces the internal path.</p>

<p>Returns the number of new steps created.</p>

<h2><a class='u'
name="clone"
>clone</a></h2>

<pre>    my $same_path    = $path-&#62;clone;
    my $similar_path = $path-&#62;clone($new_path);</pre>

<p>Clones the path object and returns it.</p>

<p>Optionally takes another path (object or string or whatever) and puts that path into the clone. This is handy if you want to use the same options and class, but just want a different path.</p>

<h2><a class='u'
name="normalize"
>normalize</a></h2>

<pre>    $path-&#62;normalize;</pre>

<p>Normalizes the steps in the path. This ensures that the keys of the step hash and the steps will be the same thing. Or to put it another way, this will make a &#34;round trip&#34; of string-to-path-to-string work commutatively. For example, if the following paths were <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3ADZIL" class="podlinkpod"
>DZIL</a> paths:</p>

<pre>    &#39;&#34;Oh, but it can...&#34; said the spider&#39;.[0].value   # Before normalize
    &#34;\&#34;Oh, but it can...\&#34; said the spider&#34;[0].value  # After normalize
 
    a.b...c[0].&#34;&#34;.&#34;&#34;.&#39;&#39;      # Before normalize
    a.b.&#34;&#34;.&#34;&#34;.c[0].&#34;&#34;.&#34;&#34;.&#34;&#34;  # After normalize</pre>

<p>Returns itself for chaining.</p>

<h2><a class='u'
name="cleanup"
>cleanup</a></h2>

<pre>    $path-&#62;cleanup;</pre>

<p>Cleans up the path. Think of this in terms of <code>cleanup</code> within <a href="http://search.cpan.org/perldoc?Path%3A%3AClass" class="podlinkpod"
>Path::Class</a>. This will remove unnecessary relative steps, and try as best as possible to present an absolute path, or at least one that progresses in a sequential manner. For example, if the following paths were <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3AFile%3A%3AUnix" class="podlinkpod"
>File::Unix</a> paths:</p>

<pre>    /foo/baz/../foo.txt   # /foo/foo.txt
    /foo//baz/./foo.txt   # /foo/baz/foo.txt
    ../../foo/../bar.txt  # ../../bar.txt
    ./command             # command</pre>

<p>Returns itself for chaining.</p>

<h1><a class='u'
name="UTILITY_METHODS"
>UTILITY METHODS</a></h1>

<p>These step conversion methods are available to use, but are somewhat internal, so they might be subject to change. In most cases, you can use the more public methods to achieve the same goals.</p>

<h2><a class='u'
name="key2hash"
>key2hash</a></h2>

<pre>    my $step_hash = $path-&#62;key2hash($key, $type, $pos);
    my $step_hash = $path-&#62;key2hash($key, $type);</pre>

<p>Figures out the missing pieces of a key/type pair, and returns a complete four-key step hash. The <a href="#normalize" class="podlinkpod"
>&#34;normalize&#34;</a> method works by throwing away the existing step and using this method.</p>

<p>Since pos translation works by using both step+delimiter, and <code>key2hash</code> doesn&#39;t have access to the delimiter, it&#39;s more accurate to pass the pos value than leave it out.</p>

<h2><a class='u'
name="path_str2array"
>path_str2array</a></h2>

<pre>    my $path_array = $path-&#62;path_str2array($path_str);</pre>

<p>Converts a path string into a path array (of step hashes).</p>

<h2><a class='u'
name="shift_path_str"
>shift_path_str</a></h2>

<pre>    my $step_hash = $self-&#62;shift_path_str(\$path_str);</pre>

<p>Removes a step from the beginning of the path string, and returns a complete four-key step hash. This is the workhorse for most of Parse::Path&#39;s use cases.</p>

<h2><a class='u'
name="blueprint"
>blueprint</a></h2>

<pre>    my $data = $self-&#62;blueprint-&#62;{$blueprint_key};</pre>

<p>Provides access to the blueprint for parsing the path style. More informaton about what this hashref contains in the <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3ARole%3A%3APath" class="podlinkpod"
>role documentation</a>.</p>

<p>Cloned for sanity. Create your own Path class if you need to change the specs.</p>

<h1><a class='u'
name="OVERLOADS"
>OVERLOADS</a></h1>

<p>In addition to its standard methods, Parse::Path also has several <a href="http://search.cpan.org/perldoc?overload" class="podlinkpod"
>overloads</a> that are useful:</p>

<h2><a class='u'
name="String_Concatenation_(.=)"
>String Concatenation (.=)</a></h2>

<pre>    $path .= &#39;q.r.s[1]&#39;;
    $path .= [qw( q r s[1] )];</pre>

<p>Modifies the path by calling <a href="#push" class="podlinkpod"
>&#34;push&#34;</a> on the RHS thing.</p>

<h2><a class='u'
name="Numeric_Comparisons"
>Numeric Comparisons</a></h2>

<pre>    $pathA &#60;  $pathB
    $pathA &#60;= $pathB
    $pathB &#62;  $pathA
    $pathB &#62;= $pathA
    $pathA == $pathA
    $pathA != $pathB
    $pathA &#60;=&#62; $pathB</pre>

<p>Uses <a href="#depth" class="podlinkpod"
>&#34;depth&#34;</a> for the numeric comparison. Still works in cases of a non-path on one side.</p>

<h2><a class='u'
name="String_Comparisons"
>String Comparisons</a></h2>

<pre>    $pathA lt $pathB
    $pathA le $pathB
    $pathB gt $pathA
    $pathB ge $pathA
    $pathA eq $pathA
    $pathA ne $pathB
    $pathA cmp $pathB</pre>

<p>If both sides are P:P objects, each key of the path is compared separately until a difference is found. This effectively bypasses delimiters as an obstacle for path comparisons. If a step is found to be an ARRAY type on both sides, a numeric comparison (<code>&#60;=&#62;</code>) is done. Mismatched step types are allowed (and checked with <code>cmp</code>), so sanity check your paths if this isn&#39;t desired.</p>

<p>If either side is a non-path, this will fallback to a simple path string comparison.</p>

<h2><a class='u'
name="Other_overloads"
>Other overloads</a></h2>

<pre>    !$path   # !$path-&#62;step_count  (ie: does the path contain anything?)
    &#34;$path&#34;  # $path-&#62;as_string
    0+$path  # $path-&#62;depth
    $$path   # $path-&#62;as_string
    @$path   # @{ $path-&#62;as_array }</pre>

<p>These all work pretty much as you&#39;d expect them to.</p>

<h1><a class='u'
name="CONVERSION"
>CONVERSION</a></h1>

<p>Different path styles can be used with ease. Convert Unix paths to Window paths? No problem:</p>

<pre>    my $unix_path = Parse::Path-&#62;new(
       path  =&#62; &#39;/root/tmp/file.txt&#39;,
       style =&#62; &#39;File::Unix&#39;
    );
 
    my $win_path  = Parse::Path-&#62;new(
       path   =&#62; $unix_path,
       style  =&#62; &#39;File::Win32&#39;,
    );
 
    $win_path-&#62;as_string;  # \root\tmp\file.txt
    $win_path-&#62;volume(&#39;C&#39;);
    $win_path-&#62;as_string;  # C:\root\tmp\file.txt
 
    $win_path-&#62;splice(-1, 1, &#39;..\foobar.gif&#39;);
    $win_path-&#62;cleanup-&#62;as_string;  # C:\root\foobar.gif
 
    $unix_path-&#62;replace($win_path);
    $unix_path-&#62;as_string;  # /root/foobar.gif</pre>

<h1><a class='u'
name="CAVEATS"
>CAVEATS</a></h1>

<h2><a class='u'
name="Absolute_paths_and_step_removal"
>Absolute paths and step removal</a></h2>

<p>Steps can be removed from the path as needed, but keep in mind that <a href="#cleanup" class="podlinkpod"
>&#34;cleanup&#34;</a> doesn&#39;t get called methods like <a href="#shift" class="podlinkpod"
>&#34;shift&#34;</a>, even if <a href="#auto_cleanup" class="podlinkpod"
>&#34;auto_cleanup&#34;</a> is set. This doesn&#39;t make a difference on absolute paths as the depth they are given is permanent. Appending two absolute paths may end up cancelling each other out:</p>

<pre>    my $path = Parse::Path-&#62;new(
       path  =&#62; &#39;/root/tmp/file.txt&#39;,
       style =&#62; &#39;File::Unix&#39;,
       auto_cleanup =&#62; 1,
    );
 
    $path-&#62;shift;  # remove the blank root
    $path-&#62;shift;  # now a dangling &#39;tmp/file.txt&#39;, tied to position 2
    $path-&#62;unshift(&#39;/home/bbyrd&#39;);
    $path-&#62;as_string;  # /home/tmp/file.txt</pre>

<p>This problem can be sidestepped by using the string forms:</p>

<pre>    $path-&#62;shift;
    $path-&#62;shift;  # tmp/file.txt
    $path-&#62;replace( [ &#39;/home/bbyrd&#39;, $path-&#62;as_string ] );
    $path-&#62;as_string;  # /home/bbyrd/tmp/file.txt</pre>

<p>This may be fixed in a later release.</p>

<h2><a class='u'
name="Normalization_of_splits"
>Normalization of splits</a></h2>

<p>While <a href="#auto_normalize" class="podlinkpod"
>&#34;auto_normalize&#34;</a> controls normalization of steps, delimiter normalization is still automatic. For example:</p>

<pre>    my $path = Parse::Path-&#62;new(
       path  =&#62; &#39;foo//////bar.txt&#39;,
       style =&#62; &#39;File::Unix&#39;,
    );
    say $path-&#62;as_string;  # foo/bar.txt</pre>

<p>This is because delimiters are not actually stored anywhere after parsing. The <a href="#as_string" class="podlinkpod"
>&#34;as_string&#34;</a> method takes the hash steps and re-adds the delimiters, per rules on the blueprint of the path class. (See <a href="http://search.cpan.org/perldoc?Parse%3A%3APath%3A%3ARole%3A%3APath#delimiter_placement" class="podlinkpod"
>&#34;delimiter_placement&#34; in Parse::Path::Role::Path</a>.)</p>

<h2><a class='u'
name="Sparse_arrays_and_memory_usage"
>Sparse arrays and memory usage</a></h2>

<p>Since arrays within paths are based on indexes, there&#39;s a potential security issue with large indexes causing abnormal memory usage with certain modules that would use these paths. In Perl, these two arrays would have drastically different memory footprints:</p>

<pre>    my @small;
    $small[0] = 1;
 
    my @large;
    $large[999999] = 1;</pre>

<p>This can be mitigated by making sure the Path style you use will limit the total digits for array indexes. <a href="http://search.cpan.org/perldoc?Parse%3A%3APath" class="podlinkpod"
>Parse::Path</a> handles this on all of its paths, but it&#39;s something to be aware of if you create your own path classes.</p>

<h1><a class='u'
name="SEE_ALSO"
>SEE ALSO</a></h1>

<p><a href="http://search.cpan.org/perldoc?Data%3A%3ASplitSerializer" class="podlinkpod"
>Data::SplitSerializer</a> - Uses this module for path parsing</p>

<h1><a class='u'
name="AVAILABILITY"
>AVAILABILITY</a></h1>

<p>The project homepage is <a href="https://github.com/SineSwiper/Parse-Path/wiki" class="podlinkurl"
>https://github.com/SineSwiper/Parse-Path/wiki</a>.</p>

<p>The latest version of this module is available from the Comprehensive Perl Archive Network (CPAN). Visit <a href="http://www.perl.com/CPAN/" class="podlinkurl"
>http://www.perl.com/CPAN/</a> to find a CPAN site near you, or see <a href="https://metacpan.org/module/Parse::Path/" class="podlinkurl"
>https://metacpan.org/module/Parse::Path/</a>.</p>

<h1><a class='u'
name="SUPPORT"
>SUPPORT</a></h1>

<h2><a class='u'
name="Internet_Relay_Chat"
>Internet Relay Chat</a></h2>

<p>You can get live help by using IRC ( Internet Relay Chat ). If you don&#39;t know what IRC is, please read this excellent guide: <a href="http://en.wikipedia.org/wiki/Internet_Relay_Chat" class="podlinkurl"
>http://en.wikipedia.org/wiki/Internet_Relay_Chat</a>. Please be courteous and patient when talking to us, as we might be busy or sleeping! You can join those networks/channels and get help:</p>

<ul>
<li>irc.perl.org
<p>You can connect to the server at &#39;irc.perl.org&#39; and talk to this person for help: SineSwiper.</p>
</li>
</ul>

<h2><a class='u'
name="Bugs_/_Feature_Requests"
>Bugs / Feature Requests</a></h2>

<p>Please report any bugs or feature requests via <a href="https://github.com/SineSwiper/Parse-Path/issues" class="podlinkurl"
>https://github.com/SineSwiper/Parse-Path/issues</a>.</p>

<h1><a class='u'
name="AUTHOR"
>AUTHOR</a></h1>

<p>Brendan Byrd &#60;bbyrd@cpan.org&#62;</p>

<h1><a class='u'
name="COPYRIGHT_AND_LICENSE"
>COPYRIGHT AND LICENSE</a></h1>

<p>This software is Copyright (c) 2013 by Brendan Byrd.</p>

<p>This is free software, licensed under:</p>

<pre>  The Artistic License 2.0 (GPL Compatible)</pre>

<!-- end doc -->

</body></html>