Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

URI plus File::Spec::Unix -- good idea or bad?

by mreece (Friar)
on Aug 24, 2006 at 20:43 UTC ( [id://569448]=perlquestion: print w/replies, xml ) Need Help??

mreece has asked for the wisdom of the Perl Monks concerning the following question:

background: i have to deal with a lot of configuration variables for paths and URIs. these being entered by humans, there is no guarantee that the path|uri does or does not end with a slash.

solution? for files, this is easy; use File::Spec:
use File::Spec; my $filepath = File::Spec->catfile( $dir, $filename );
but what about URIs? i don't see any handy methods on the URI class for appending values. so i had an idea, i could use File::Spec::Unix to manipulate the path portion of the URI.
use File::Spec::Unix; use URI; my $uri = URI->new( $base ); $uri->path( File::Spec::Unix->catfile( $uri->path, 'foo.html' ) );
my question is, is this a good idea or bad idea? am i overlooking an existing best/common practice for dealing with this?

Replies are listed 'Best First'.
Re: URI plus File::Spec::Unix -- good idea or bad?
by brian_d_foy (Abbot) on Aug 24, 2006 at 21:13 UTC

    URLs are the same everywhere you go, so you don't need the localization magic of File::Spec to figure out how to put them together. Just use the forward slash (/) to join the path elements. It's so trivial I guess URI doesn't see fit to wrap it in a method name. :)

    So, in your example, if $uri->path ends in a slash, just concatenate the foo.html. If the $uri->path doesn't end in a slash, make it end in a slash, then add the foo.html. That's just what File::Spec::Unix->catfile is doing, although you're not really supposed to be peeking down there. :) If that's all your using that module for, it's probably not worth it to even compile it. :)

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
      of course, but my goal is to avoid the "if the $uri->path doesn't end in a slash do something different" part, if possible.
      $uri->path( $uri->path =~ m{/$} ? $uri->path . 'index.html' : $uri->pa +th . '/index.html')
      and similar seems more clumsy.

      what i actually end up with is typically more like $base .= '/' unless $base =~ m{/$};, but i'm looking for something smarter, because i hate repeating these things and the problem is so easily solved (use File::Spec) with other file paths outside of URI context.

      as for localization, that's why i used File::Spec::Unix explicitly, because you are correct, i don't need localization magic.
        Slightly less clumsy?
        $uri->path( $uri->path .( $uri->path =~ m{/$} ? '' : '/' ) .'index.html' );
Re: URI plus File::Spec::Unix -- good idea or bad?
by insaniac (Friar) on Aug 24, 2006 at 21:19 UTC
    you could use a simple regex of course:
    $_="http://bla.com"; s#([^/])$#$1/#; $_ .= "foo.html"; print; # prints http://bla.com/foo.html $_="http://bla.com/"; s#([^/])$#$1/#; $_ .= "foo.html"; print; # prints http://bla.com/foo.html
    always a million ways to do things ;-)

    to ask a question is a moment of shame
    to remain ignorant is a lifelong shame

Re: URI plus File::Spec::Unix -- good idea or bad?
by izut (Chaplain) on Aug 24, 2006 at 23:51 UTC

    Check URI::file. It seems to suit your needs.

    Update: Sorry, misread the OP. Anyways, it has a hint about it:

    If you simply want to construct file URI objects from URI strings, use + the normal URI constructor. If you want to construct file URI object +s from the actual file names used by various systems, then use one of + the following URI::file constructors: ...

    Igor 'izut' Sutton
    your code, your rules.

      that is for file://-schemed URIs, not http, and it doesn't do concatenation, so i have trouble seeing how it could be of use here, unless i am missing something.
Re: URI plus File::Spec::Unix -- good idea or bad?
by Anonymous Monk on Aug 25, 2006 at 13:36 UTC
    Bad idea. Generic methods both set and return ...
    #!/usr/bin/perl -- use strict; use warnings; use URI; my $base = 'http://foobert.org/dir/odir'; my $file = 'foo.html'; my $uri = URI->new($base); local $\=$/; print $uri->path_segments( $uri->path_segments, $file ); print $uri; print $uri->host('I-RTFM.org'); print $uri; __END__ dirodir http://foobert.org/dir/odir/foo.html foobert.org http://I-RTFM.org/dir/odir/foo.html
      $uri->path_segments is interesting and useful, but it doesn't solve the "behave the same whether $base ends with a slash or not" problem.

      change the code to my $base = 'http://foobert.org/dir/odir/'; and you get http://foobert.org/dir/odir//foo.html, with two slashes!

        however, this will do it :)
        print $uri->path_segments( grep { $_ } $uri->path_segments, $file );
        uses grep to filter out the empty strings returned by path_segments.

        updated: fixed typo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://569448]
Approved by philcrow
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-25 09:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found