开发者

One liner to access an array element in perl?

I have the following:

my @path = split( "/", getcwd );
my $grandParent = $path[-2];

I'd like to do it in one line (like in other languages) since I'm not using @开发者_如何学运维path again, like so:

my $grandParent = split( "/", getcwd )[-2];

Is this possible? If so, how?

EDIT: Just to be clear - where I am running the script from I know some things are going to be invariant (the directory structure, names, etc). This being said, validation is nice, but in this scenario is more clutter than it is worth; thanks to those who submitted solutions with error checking any ways.


Put the results of the split in a temporary list:

my $grandParent = (split( "/", getcwd ))[-2];


should be:

use Cwd;
...

my $grandParent = ( split '/', getcwd ) [-2];

Addendum: another way (somehow more 'perlish'):

...

my ($parent, $grandParent) = reverse split qr{/}, getcwd();

(taking into account some of tchrist's good advice)

Addendum 2: Some comment:

Sometimes, there might not be a $grandparent directory at all. If used in the root dir on a Unix system '/', above will result in:

 $parent = undef;
 $grandParent = undef;

if in a directory directly below '/', eg. '/somedir',

 $parent = 'somedir';
 $grandParent = ''; # empty string

so you may check for that condition. Furthermore, the reverse reverses the order of the elements of the splitted path, so you know you need to look at the (now) first two elements to know where you are.

Regards

rbo


Thinngs to remember:

  1. You have to account for not getting enough list elements back, and also for when the applicable element ends up being the empty string.
  2. split()’s first argument is a pattern, not a string, so you should remind people of that by writing it as a match operation.
  3. getcwd() is a nullary function, not a bareword, so you should remind people of that by using empty parens.

    $grandparent = ( split(m{ / }x, getcwd()) )[-2] || "/";
    

That won’t work on non-POSIX filesystems; instead, see File::Spec.

Please ignore SO’s idiotic colorizificationalistics, which do more harm than good.


A portable way is to use splitdir method of File::Spec:

use Cwd;
use File::Spec;

my $grand_parent = ( File::Spec->splitdir( getcwd() ) )[-2] || File::Spec->rootdir();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜