Нет, они не эквивалентны, но вы близко. Чтобы показать вам почему, я возьму в качестве аксиоматики c эти два правила:
Эти два выражения эквивалентны:
a.collect {|x| pred(x) }.all?
a.all? {|x| pred(x) }
Эти два выражения эквивалентны:
a.all? {|x| pred(x) }
!a.any? {|x| !pred(x) }
Давайте применим это к вашему коду. Во-первых, вытащите логи c из своего блока, чтобы было немного легче рассуждать о:
def pred(char)
utf8?(char) && char.blank?
end
!char_list.collect {|char| pred(char) }.all?
Теперь, применяя аксиому (1), мы можем изменить выражение .collect {...}.all?
на .all? {...}
, что дает нам:
!char_list.all? {|char| pred(char) }
Применяя аксиому (2), мы можем превратить выражение all?
в отрицательное any?
:
!!char_list.any? {|char| !pred(char) }
Конечно, двойное отрицание (!!
) - это то же самое, что отсутствие отрицания, поэтому мы имеем:
char_list.any? {|char| !pred(char) }
... и, наконец, мы можем поместить логи c обратно в блок:
char_list.any? {|char| !(utf8?(char) && char.blank?) }
Как вы можете видеть, вы были почти у цели, но вместо того, чтобы просто отрицать char.blank?
, вам нужно было свести на нет все выражение внутри блока.