Илья (>): >> my @a = <a b c d>; my @b = <b d>; say @a.grep: { $_ eq any(@b) }; > bd > >> my @a = <a b c d>; my @b = <b d>; say @a.grep: { $_ ne any(@b) }; > abcd > > hm. I expect: ac > But Rakudo and PUGS both return abcd. May by I missed something?
If you expected "ac", then you probably expected "$_ ne any(@b)" to mean "$_ is not equal to any element in @b". This is a reasonable expectation, but unfortunately, it's wrong. Why? Well, "any(@b)" expands into "'b' | 'd'", i.e. an or-junction (a 'disjunction') of 'b' and 'd'. Because of the junction, the "ne" comparison turns into the expression "$_ ne 'b' || $_ ne 'd'", which is always true, since something is always distinct from at least one of two distinct strings. Take-home message: you never want to use negative comparison operators and junctions together. They don't do what you think. Use prefix "not" instead: $ ./perl6 -e 'my @a = <a b c d>; my @b = <b d>; say @a.grep: { not $_ eq any(@b) }' ac >> my @a = <a b c d>; my @b = <b d>; say @a.grep: { $_ eq none(@b) }; > ac > >> my @a = <a b c d>; my @b = <b d>; say @a.grep: { $_ ne none(@b) }; > > I expected ac there too. Hm. "The element is not equal to none of @b"? :-) Somehow I doubt that this expression falls under "self-explanatory" code. Anyway, the expression turns into something like "!($_ ne 'b') && !($_ ne 'd')", which is why you get an empty result back, because something cannot be equal to both 'b' and 'd' at the same time. So, again: don't mix negated operators and junctions. It even says so in S02: ] Use of negative operators with syntactically recognizable junctions ] may produce a warning on code that works differently in English than ] in Perl. Instead of writing ] ] if $a != 1 | 2 | 3 {...} ] ] you need to write ] ] if not $a == 1 | 2 | 3 {...} ] ] However, this is only a syntactic warning, and ] ] if $a != $b {...} ] ] will not complain if $b happens to contain a junction at runtime. // Carl