Рубокоп, безопасная навигация и отрицание
У меня есть такие конструкции, на которые Рубокоп жалуется, что я пытаюсь успокоить
unless foo && !foo.empty? ...
(элемент существует и не пуст)
а также
bar && !bar.positive?
(пункт существует и не является положительным)
В обоих случаях Рубокоп бросает Style/SafeNavigation
и говорит, что я должен использовать &.
вместо. Однако, кажется, нет способа написать это.
В обоих случаях часть проблемы заключается в том, что нет краткого способа выражения противоположной функции - нет "непустых" для строк и "отрицательных или нулевых" для чисел. Пишу bar&.negative?
например, возвращает нулевой результат для нуля.
В другом случае написание unless !foo&.empty?
Рубокоп пожаловался, если только не отрицание, но опять же нет способа переписать его как if foo&.
с любой операцией, которая существует.
(кстати это прямой Ruby, без Rails, поэтому у меня нет blank?
а также present?
)
2 ответа
Это упущение в RuboCop, потому что предлагаемое исправление не может иметь одинаковую семантику. Это будет исправлено в следующем патче 0.50.1, и полицейский будет игнорировать дела с отрицанием.
В то же время, если вы имеете дело с условиями, где ваша переменная может быть nil
Одним из вариантов является использование того факта, что nil
реагирует на методы принуждения. Пример, предполагая foo
это либо массив, либо nil
:
# With nil check
unless foo && !foo.empty?
# With array coercion
if foo.to_a.empty?
Это:
next unless foo && !foo.empty?
Может быть заменено на:
next if foo.nil? || foo.empty?
И аналогично, это:
next unless bar && !bar.positive?
Может быть заменено на:
next if bar.nil? || bar.positive?
Реальный запах кода здесь, по моему мнению, был next unless ... not
, Двойной отрицательный знак означает, что, вероятно, есть более чистый способ написать это.