Вложенные стрелки разыменования в Perl: опустить или не опустить?

В Perl, когда у Вас есть вложенная структура данных, допустимо опустить разыменовывать стрелки к 2-му и большему уровню вложения. Другими словами, следующие два синтаксиса идентичны:

my $hash_ref = { 1 => [ 11, 12, 13 ], 3 => [31, 32] };

my $elem1 = $hash_ref->{1}->[1]; 
my $elem2 = $hash_ref->{1}[1]; # exactly the same as above

Теперь, мой вопрос, существует ли серьезное основание выбрать один стиль по другому?

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

До сих пор почти ни один из обычных подозреваемых не говорит ничего категорического:

  • perldoc просто говорит, что "Вы свободны опустить стрелку разыменования указателя".
  • "Лучшие практики Perl Conway" говорит, "когда это возможно, разыменуйте со стрелками", но это, кажется, только относится к контексту разыменования основной ссылки, не дополнительных стрелок на 2-м уровне вложенных структур данных.
  • "Освоение Perl для Bioinfirmatics" автор James Tisdall не дает очень твердое предпочтение также:

    "Сообразительный читатель, возможно, заметил, что мы, кажется, опускаем операторы стрелки между нижними индексами массива. (В конце концов, это анонимные массивы анонимных массивов анонимных массивов, и т.д., таким образом, разве они не должны быть записаны [$array->[$i]-> [$j]-> [$k]?) Perl позволяет это; только оператор стрелки между именем переменной и первым нижним индексом массива требуется. Это делает вещи легче на глазах, и помогает избежать синдрома канала запястья. С другой стороны, можно предпочесть удерживать стрелки разыменования на месте, прояснять, что Вы имеете дело со ссылками. Ваш выбор".

  • ОБНОВЛЕННЫЙ "Промежуточный Perl", согласно его соавтору brian d foy, рекомендует опустить стрелки. См. полный ответ brian ниже.

Лично, я нахожусь на стороне "всегда вставляемых стрелок, так как это более читаемо и очевидно, что они имеют дело со ссылкой".

ОБНОВЛЕНИЕ, Чтобы быть более определенным ре: удобочитаемость, в случае мультивложенного выражения, где сами нижние индексы являются выражениями, стрелки, помогает к, "визуально маркируют" выражения, более очевидно, отделяющимися нижними индексами друг от друга.

7
задан Community 23 May 2017 в 12:01
поделиться

3 ответа

Если вам не очень нравится набирать текст или слишком длинные строки, не используйте стрелки, когда они не нужны. Подскрипты рядом с подскриптами подразумевают ссылки, поэтому грамотному программисту не нужны дополнительные подсказки, чтобы понять это.

Я не согласен с тем, что наличие дополнительных стрелок делает текст более читабельным. Определенно нетрадиционно, когда они перемещают интересные части термина дальше друг от друга.

В Intermediate Perl, где мы действительно учим ссылкам, мы говорим вам опускать лишние стрелки.

Также помните, что не существует такого понятия, как "читабельность". Есть только то, что вы (и другие) приучили свои глаза распознавать как паттерны. Вы не читаете текст за текстом, чтобы понять, что они означают. Вы видите группы вещей, которые вы видели раньше, и узнаете их. На уровне базового синтаксиса, о котором вы говорите, ваша "читабельность" - это просто ваша способность распознавать шаблоны. Чем больше вы пользуетесь языком, тем легче распознавать шаблоны, поэтому неудивительно, что то, что вы делаете сейчас, для вас более "читабельно". Новые стили поначалу кажутся странными, но со временем они становятся более узнаваемыми, а значит, более "читаемыми".

Пример, который вы приводите в своих комментариях, трудно читать не потому, что в нем нет стрелок. Он все равно трудночитаем со стрелками:

 $expr1->[$sub1{$x}]{$sub2[$y]-33*$x3}{24456+myFunct($abc)}
 $expr1->[$sub1{$x}]->{$sub2[$y]-33*$x3}->{24456+myFunct($abc)}

Я пишу подобный код вот так, используя такие имена переменных, чтобы напомнить следующему кодеру о том, каким контейнером является каждый уровень:

my $index = $sub1{$x};
my $key1  = $sub2[$y]-33*$x3;
my $key2  = 24456+myFunct($abc);

$expr1->[ $index ]{ $key1 }{ $key2 };

Чтобы сделать это еще лучше, спрячьте детали в подпрограмму (для этого они и существуют :), чтобы вам никогда не пришлось играть с этой беспорядочной структурой данных напрямую. Это более читабельно, чем любой из них:

  my $value = get_value( $index, $key1, $key2 );

  my $value = get_value(
  $sub1{$x},
   $sub2[$y]-33*$x3,
   24456+myFunct($abc)
      );
14
ответ дан 6 December 2019 в 11:48
поделиться

Поскольку стрелка -> необязательно используется для вызовов методов, я предпочитаю использовать ее только для вызова кода. Поэтому я бы использовал следующее:

$object->method;
$coderef->();
$$dispatch{name}->();

$$arrayref[1];
$$arrayref[1][5];
@$arrayref[1 .. 5];
@$arrayref;
$$hashref{foo};
$$hashref{foo}{bar};
@$hashref{qw/foo bar/};
%$hashref;

Две сигилы, расположенные вплотную друг к другу, всегда означают разыменование, и структура остается согласованной во всех формах разыменования (скаляр, срез, все).

Он также сохраняет все части переменной «вместе», что я считаю более читаемым и более коротким :)

2
ответ дан 6 December 2019 в 11:48
поделиться

Я всегда писал все стрелками. Я согласен с вами, они лучше отделяют различные субскрипты. Кроме того, я использую фигурные скобки для регулярных выражений, поэтому для меня {foo}{bar} - это подстановка: s{foo}{bar} больше отличается от $s->{foo}->{bar}, чем от $s->{foo}{bar}.

Однако я не думаю, что это большая проблема, чтение кода, в котором отсутствуют дополнительные стрелки, не является проблемой (в отличие от любого отступа, который не используется мной ;--)

.
1
ответ дан 6 December 2019 в 11:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: