При каких обстоятельствах этот оператор короткого замыкания ИЛИ возвращает второе определение этой функции сортировки? - PullRequest
0 голосов
/ 25 апреля 2019

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

if ($sorttype == 2) {
    $subsort = ( sub { $a->{key2} <=> $b->{key2} } );
}
elsif ($sorttype == 3) {
    $subsort = ( sub { $a->{key3} <=> $b->{key3} || $a->{defaultKey} <=> $b->{defaultKey} } );
}
elsif ($sorttype == 4) {
    $subsort = ( sub { $b->{defaultKey} <=> $a->{defaultKey} } );
}
elsif ($sorttype == 5) {
    $subsort = ( sub { $b->{key5} cmp $a->{key5} || $a->{defaultKey} <=> $b->{defaultKey} } );
}

где базовый шаблон выглядит так:

$subsort = ( sub{keyComparison || defaultComparison} );

$subsort вызывается позже таким образом:

foreach (sort $subsort @dataArray) {
    my $data = $_;
    ...
}

Я не понимаю, как использовать здесь оператор короткого замыкания ИЛИ.
При каких возможных обстоятельствах, если таковые имеются, $subsort будет определяться defaultComparison?

В качестве дополнительного вопроса, есть ли смысл оборачивать это в контекст списка (например, в скобках)?
Под этим я подразумеваю:

$subsort = ( sub{keyComparison || defaultComparison} );

# versus

$subsort = sub{keyComparison || defaultComparison};

Примечание:
Если кто-то может придумать более подходящее название для этого вопроса, пожалуйста, отредактируйте его (я подозреваю, что, если бы я смог придумать более подходящее название, мой google-fu не подвел бы меня).

1 Ответ

5 голосов
/ 25 апреля 2019

Я полагаю, вы спрашиваете о

$a->{key3} <=> $b->{key3} || $a->{defaultKey} <=> $b->{defaultKey}

Если есть сомнения, это анализируется как

( $a->{key3} <=> $b->{key3} ) || ( $a->{defaultKey} <=> $b->{defaultKey} )

Поскольку || короткое замыкание, его RHS ($a->{defaultKey} <=> $b->{defaultKey}) будет оцениваться только в том случае, если его LHS ($a->{key3} <=> $b->{key3}) вернет false. Итак, ваш вопрос сводится к следующему:

Когда $a->{key3} <=> $b->{key3} возвращает false?

<=> оценивается как

  • -1, если его LHS численно меньше, чем его RHS.
  • 0, если его LHS численно равен его RHS.
  • + 1, если его LHS численно больше, чем его RHS.

Это означает, что $a->{key3} <=> $b->{key3} оценивается как

  • -1, если $a->{key3} < $b->{key3}
  • 0, если $a->{key3} == $b->{key3}
  • + 1, если $a->{key3} > $b->{key3}

Из этих трех значений только 0 является ложным. Это единственный раз, когда оценивается RHS ||.

Это означает, что $a->{key3} <=> $b->{key3} || $a->{defaultKey} <=> $b->{defaultKey} оценивается как

  • -1, если $a->{key3} < $b->{key3}
  • -1, если $a->{key3} == $b->{key3} && $a->{defaultKey} < $b->{defaultKey}
  • 0, если $a->{key3} == $b->{key3} && $a->{defaultKey} == $b->{defaultKey}
  • + 1, если $a->{key3} == $b->{key3} && $a->{defaultKey} > $b->{defaultKey}
  • + 1, если $a->{key3} > $b->{key3}

При использовании в качестве функции сравнения sort элементы сортируются по key3, а связи defaultKey.

.
+------------+------------+
| key3       | defaultKey |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          1 |          3 |
|          2 |          1 |
|          2 |          2 |
|          2 |          3 |
|          3 |          1 |
|          3 |          2 |
|          3 |          3 |
+------------+------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...