Почему smartmatch возвращает true при сравнении фрагментов массива, которые должны отличаться? - PullRequest
8 голосов
/ 07 февраля 2012

Следующий скрипт смарт-сопоставляет фрагменты двух массивов.В начале оба массива одинаковы, и я получаю разумные результаты.Затем я меняю один из массивов и сопоставляю два новых среза, но он все равно говорит, что срезы идентичны.Однако, когда я копирую срезы в массивы, интеллектуальное сопоставление массивов показывает, что они действительно разные.

Сценарий:

#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;

my @x = qw (one two);
my @y = qw (one two);
my @x_s;
my @y_s;

print "Before change: values are the same:\n";
@x_s = @x[0,1];
@y_s = @y[0,1];
print "\@x_s: @x_s\n";
print +(@x[0,1] ~~ @y[0,1]) ? "equal\n" : "not equal\n";
print +(@x_s ~~ @y_s) ? "equal\n" : "not equal\n";

$x[0]='three';

print "After change: values should be different:\n";
@x_s = @x[0,1];
@y_s = @y[0,1];
print "\@x_s: @x_s\n";
print +(@x[0,1] ~~ @y[0,1]) ? "equal\n" : "not equal\n";
print +(@x_s ~~ @y_s) ? "equal\n" : "not equal\n";

Вывод:

Before change: values are the same:
@x_s: one two
equal
equal
After change: values should be different:
@x_s: three two
equal
not equal

Я использую Perl 5.10.1, и это происходит как для фрагментов массива, так и для хеш-фрагментов.Почему это происходит?

Ответы [ 3 ]

5 голосов
/ 07 февраля 2012

Похоже, что интеллектуальное сопоставление работает в скалярном контексте с кусочками.

Рассмотрим следующие фрагменты кода:

Ваш случай:

#!/usr/bin/perl

my @foo = (1,2);
my @bar = (3,4);
print @foo[1,2] ~~ @bar[1,2] ? "Equal\n" : "Not equal\n";

Это, вероятно, то, что вам нужно:

#!/usr/bin/perl

my @foo = (1,2);
my @bar = (3,4);
print [ @foo[1,2] ] ~~ [ @bar[1,2] ] ? "Equal\n" : "Not equal\n";
3 голосов
/ 07 февраля 2012

Оператор умного сопоставления ~~ делает свое дело для массивов, а не для списков. Срез массива - это список, а не массив.

Обновление:

Вы можете решить эту проблему, просто заключив свои фрагменты в скобки, поскольку интеллектуальное сопоставление автоматически разыменовывается:

print +([@x[0,1]] ~~ [@y[0,1]]) ? "equal\n" : "not equal\n";
0 голосов
/ 21 сентября 2016

Первоначально опубликовано askucins

Я выполнил быстрый запрос в документации по Perl, связанный с различным поведением этого теста по сравнению с версией Perl, и обнаружил, что это было исправлено в Perl 5.13.5. См. «Умное сопоставление с фрагментами массива» в perl5135delta :

Ранее следующий код приводил к успешному совпадению:

my @a = qw(a y0 z);
my @b = qw(a x0 z);
@a[0 .. $#b] ~~ @b;

Это странное поведение теперь исправлено [ perl # 77468 ].

...