Вложенные стрелки разыменования в Perl: пропускать или не пропускать? - PullRequest
7 голосов
/ 19 марта 2010

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

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

Теперь, мой вопрос: есть ли веская причина выбрать один стиль вместо другого ?

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

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

  • perldoc просто говорит: «Вы можете опустить стрелку разыменования указателя».
  • В «Perl Best Practices» Конвея говорится «когда это возможно, разыменование стрелками», но, похоже, это применимо только к контексту разыменования главной ссылки, а не дополнительных стрелок на 2-м уровне вложенных структур данных.
  • Автор «Мастеринг Perl для биоинформатики», Джеймс Тисдалл, также не дает очень веских предпочтений:

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

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

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

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

Ответы [ 3 ]

14 голосов
/ 19 марта 2010

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

Я не согласен с тем, что более удобные для чтения дополнительные стрелки. Совершенно нетрадиционно, когда они отодвигают интересные части этого термина друг от друга.

В Промежуточном 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)
      );
2 голосов
/ 19 марта 2010

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

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

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

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

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

1 голос
/ 19 марта 2010

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

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

...