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

I keep running into this. I have a Path::Class object and I want the "last part" of it. So for:

/my/path/some_dir/
/my/path/some_file.txt
I want to get "some_dir" or "some_file.txt" respectively. If my object is a Path::Class::File object, I can call ->basename. If it's a Path::Class::Dir, I can call ->dir_list(-1). What if I don't want to know/care whether it's a ::File or ::Dir? Sure I can do:
my $last_part = $p->is_dir ? $p->dir_list(-1) : $p->basename;
but it seems like there should be something simpler. Or something like that should be available as a method on Path::Class::Entity (the superclass of ::File and ::Dir).

Thanks for any thoughts.

Replies are listed 'Best First'.
Re: get the "last part" of a Path::Class object
by moritz (Cardinal) on Jun 22, 2007 at 20:33 UTC
    This being perl I have to suggest a regex solution:

    m#([^/]+)/*$# # and use $1 now

      This being Perl, you run into trouble once you are on another file-system which uses different delimiters.
Re: get the "last part" of a Path::Class object
by holli (Abbot) on Jun 23, 2007 at 00:57 UTC
    Not that it would help you much now, but once I get around to upload my FileSystemObjects-module to CPAN you could simply use $fso->name. Wanna betatest? (It's pretty stable right now besides some minor issues of resolving relative paths to absolute paths).


    holli, /regexed monk/
Re: get the "last part" of a Path::Class object
by Anonymous Monk on Jun 23, 2007 at 01:51 UTC
    sub Path::Class::Entity::last_part { my $p = shift; return $p->is_dir ? $p->dir_list(-1) : $p->basename; }
Re: get the "last part" of a Path::Class object
by mrpeabody (Friar) on Jun 23, 2007 at 19:44 UTC
    It's absurd that these two classes don't have a method with the same name for this common operation. The obvious solution is patching Path::Class::Dir to get (pseudocode):
    sub Path::Class::Dir::basename { return $self->dir_list(-1); }

    Alternatively, this idiom would probably work for most cases:

    file($p)->basename;
Re: get the "last part" of a Path::Class object
by naikonta (Curate) on Jun 25, 2007 at 01:25 UTC
    I wasn't aware about Path::Class. I was suprised upon reading the docs that it provides two distinct objects without a base implementing public interfaces for common behaviours. I would just say,
    $ perl -MFile::Spec -wle 'my $path = shift; my $last = (File::Spec->sp +litpath($path))[-1]; print $last' /etc/httpd/conf conf $ perl -MFile::Spec -wle 'my $path = shift; my $last = (File::Spec->sp +litpath($path))[-1]; print $last' /etc/httpd/conf/httpd.conf httpd.conf
    I think you can just pass the object to File::Spec::splitpath() function because the class implements string overloading method. So, you don't have to care whether what you pass is ::File or ::Dir object.
    $ perl -MPath::Class -wle 'my $path = shift; my $obj = file($path); pr +int +(File::Spec->splitpath($obj))[-1]' /etc/httpd/conf/httpd.conf httpd.conf $ perl -MPath::Class -wle 'my $path = shift; my $obj = dir($path); pri +nt +(File::Spec->splitpath($obj))[-1]' /etc/httpd/conf conf
    Of course, you still have to know what object you want to create in the first place.

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!