Ruby: якщо змінний vs if varia.nil?


11

Я новачок у Рубі, і я здивувався, коли дізнався, що всі об’єкти є істинними, крім нульових і хибних. Навіть 0 правда.

Приємна річ у цій властивості мови полягає в тому, що ви можете писати:

if !variable
  # do stuff when variable is nil
end

Мої колеги, які є більш досвідченими розробниками Ruby, наполягають, що я повинен обрати це, а не використовувати .nil? так:

if variable.nil?
  # do stuff when variable is nil
end

Однак я вважаю, що остання є кращим варіантом з двох причин: 1. Я думаю, що вона більш орієнтована на об'єкти, особливо на такій мові, як Рубі, де все є об'єктом та обміном повідомленнями. 2. На мій предметний погляд він легше читається, навіть якщо він менш компактний.

Чи роблю тут помилку "новачка"?


4
Ви тестуєте на нуль? або хибне значення?

Я тестую на нуль. В основному, якщо змінна є нульовою, я щось роблю (чи ні)
Хав'єр Холгера

3
Якщо ви перевіряєте на нуль, чому ви хочете, щоб тест на помилку також входив у цей блок?

Погодьтеся, я вказав, що це ще одна причина віддати перевагу .nil? Але вони наполягали на тому, що "якщо змінна do x" є ідіоматичнішою, ніж "if varia.nil? Do x", і бажано, коли ви знаєте, що змінна не булева,
Хав'єр Холгера

Відповіді:


17

Напишіть, що ви маєте на увазі. Майте на увазі те, що ви пишете.

Давайте проведемо інший тест. .vowel?

if char == 'a'
   # do stuff
end

проти

if char.vowel?
   # do stuff
end

Тепер очевидно, що вони не роблять те саме. Але якщо ви тільки розраховуєте, що charце буде, aабо bце спрацює. Але це заплутає наступного розробника - другий блок буде введений для умов, де [eiou]також є char . Але для aцього він буде працювати правильно.

Так, саме так nilі falseє єдині хибні значення в Ruby. Однак якщо ви тестуєте nilтест на nil || false, це не те, що ви маєте на увазі.

Це означає, що наступний розробник (який випадково вбивство божевільної сокири, який знає вашу домашню адресу) прочитає код і запитає, навіщо йому falseтакож туди зайти.

Напишіть код, який передає саме те , що ви маєте на увазі.


3

Розглянемо наступне:

response = responses.to_a.first

Це поверне перший елемент responses, або nil. Тоді тому, що умовні заяви трактуються так, nilяк falseми можемо написати:

response = responses.to_a.first
if response
  # do something ('happy path')
else
  # do something else
end

Що читабельніше, ніж:

if response.nil?
  # do something else
else
  # do something ('happy path')
end

if (object)Картина дуже часто зустрічається в Ruby - коду. Це також добре призводить до рефакторингу, наприклад:

if response = responses.to_a.first
  do_something_with(response)
else
  # response is equal to nil
end

Пам'ятайте також, що метод Ruby повертається nilза замовчуванням. Так:

def initial_response
  if @condition
    @responses.to_a.first
  else
    nil
  end
end

можна спростити:

def initial_response
  if @condition
    @responses.to_a.first
  end
end

Тож ми можемо надалі рефактор:

if response = initial_response
  do_something_with(response)
else
  # response is equal to nil
end

Тепер ви можете стверджувати, що повернення nil- це не завжди найкраща ідея, оскільки це означає перевірити nilвсюди. Але це ще один чайник риби. Зважаючи на те, що тестування на предмет "присутності чи відсутності" є такою частою вимогою, правдивість об'єктів є корисним аспектом Рубі, хоч і дивно для новачків мови.


2

Він не тільки if variable.nil?читається як природна мова, але й захищає програміста, випадково привласнюючи йому falseзначення і потрапляючи у ваше ifвисловлювання, оскільки Ruby - це мова, що не вводиться.


1
Тож початковий коментар у первісному питанні був неправильним? Повинні були бути "робити речі, коли змінна нульова або помилкова"? А оскільки код, що не відповідає коментарю, - це помилка, помилка є відразу?
gnasher729

Правильно. Простий тест на правдивість може ввести логічні помилки.
Грег Бургхардт

0

Ідіоматично, unless variableпереважніше if !variable. Негативні ifвисловлювання часто вважаються кодовим запахом, оскільки легше пропустити заперечення при скимі.

Більш широка картина тут полягає в тому, що проведення nilтаких перевірок також трохи запаху коду. Для належного OO прагнете використовувати нульовий шаблон об'єкта, щоб такий вид перевірки ніколи не потрібен. http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/

Скажіть об’єктам, що робити, не запитуйте їх, що вони є. Іноді це відомо як розкажи не запитай

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.