Один вкладыш для доступа к элементу массива в Perl? - PullRequest
1 голос
/ 05 ноября 2010

У меня есть следующее:

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

Я бы хотел сделать это в одну строку (как в других языках), так как я больше не использую @path, вот так:

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

Возможно ли это? Если да, то как?

РЕДАКТИРОВАТЬ: Просто для ясности - откуда я запускаю скрипт, я знаю, что некоторые вещи будут инвариантными (структура каталогов, имена и т. Д.). Это, как говорится, проверка хороша, но в этом сценарии больше беспорядка, чем оно того стоит; спасибо тем, кто представил решения с проверкой ошибок любыми способами.

Ответы [ 4 ]

6 голосов
/ 05 ноября 2010

Положите результаты разбиения во временный список:

my $grandParent = (split( "/", getcwd ))[-2];
5 голосов
/ 05 ноября 2010

должно быть:

use Cwd;
...

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

Добавление: другой способ (как-то больше «perlish»):

...

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

(принимая во внимание некоторые из хороших советов Триста )

Приложение 2: Некоторые комментарии:

Иногда каталог $grandparent может вообще не существовать. Если используется в корневом каталоге в системе Unix '/', выше будет результат:

 $parent = undef;
 $grandParent = undef;

если в каталоге непосредственно под '/', например. '/ Somedir',

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

так что вы можете проверить это условие. Кроме того, reverse меняет порядок элементов разделенного пути, чтобы вы знали нужно взглянуть на (сейчас) первые два элемента, чтобы знать, где вы находитесь.

Привет

БВУ

4 голосов
/ 05 ноября 2010

Помните:

  1. Вы должны учитывать, что не получили достаточного количества элементов списка назад, а также за то, когда применимый элемент заканчивается пустой строкой.
  2. split() Первый аргумент - это шаблон, а не строка, поэтому вы должны напомнить об этом людям, написав его как операцию сопоставления.
  3. getcwd() - это нулевая функция, а не голое слово, поэтому вы должны напоминать об этом людям, используя пустые символы скобок.

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

Это не будет работать на файловых системах, отличных от POSIX; вместо этого см. File::Spec.

Пожалуйста, не обращайте внимания на идиотские колорициативные характеристики SO, которые приносят больше вреда, чем пользы.

2 голосов
/ 05 ноября 2010

Переносимым способом является использование splitdir метода File::Spec:

use Cwd;
use File::Spec;

my $grand_parent = ( File::Spec->splitdir( getcwd() ) )[-2] || File::Spec->rootdir();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...