Подтвердить что ты не робот

Могу ли я использовать `else if` над` elsif`?

  • Можно ли использовать else if над elsif?
  • Лучше использовать elsif, потому что он следует за строкой Ruby конвенции?
  • Или это предпочтение?

Это часть кода, взятого из книги. Я добавил дополнительные ключевые слова end и заменил ключевые слова elsif на else if s.

def describe(inhabitant)
  if inhabitant == "sophie"
    puts 'gender: female'
    puts 'height: 145'
  else if inhabitant == "paul"
    puts 'gender: male'
    puts 'height: 145'
  else if inhabitant == "dawn"
    puts 'gender: female'
    puts 'height: 170'
  else if inhabitant == "brian"
    puts 'gender: male'
    puts 'height: 180'
  else if 
    puts 'species: Trachemys scripta elegans'
    puts 'height: 6'
  end
  end 
  end   
  end
  end
end

Это заставило меня понять, насколько уродлив else if.

4b9b3361

Ответ 1

Вы можете использовать else if, и это безопасно. Однако обратите внимание, что это означает, что необходимы дополнительные ключевые слова end.

if n == 1
  puts "foo"
elsif n == 2
  puts "bar"
end

логически совпадает с:

if n == 1
  puts "foo"
else if n == 2
       puts "bar"
     end
end

или эквивалент:

if n == 1
  puts "foo"
else 
  if n == 2
    puts "bar"
  end
end

Ответ 2

TL; DR - Замена elsif на else if подходит для условного кода с двумя путями. Не забудьте закрыть второй if условный, созданный с помощью else if. Лучше всего иметь как можно меньше уровней условностей, делая менее сложный метод. Поэтому сделайте ошибку на стороне осторожности и используйте elsif.

В зависимости от того, как вы планируете писать свой метод, else if может работать. Однако это не хорошая привычка.

Возьмем следующий пример. Есть только 2 условия. Второе условие похоже на elsif, но интерпретируется как второй фрагмент кода:

# What you may want to write
if true
  puts 'true'
else if false
  puts 'false'
end

# How Ruby requires it
if true
  puts 'true'
else
  if false  # You may also do: puts 'false' if false
    puts 'false'
  end
end

Первый блок будет искать другой end, чтобы закрыть первичный условный. Обратите внимание, что вы можете обойти дополнительный конец с помощью одной строки if. (Я предлагаю это только в том случае, если исполняемый код может быть записан в одной строке.)

Важно отметить, что после объявления else у вас могут быть другие условные обозначения на том же уровне, что и else. Учитывая второй пример выше, второй if вложен в else. Если вы должны были вызвать else или elsif на том же уровне, что и исходный else, условие будет терпеть неудачу.

Вот, когда вы не захотите реализовать else if:

def describe(inhabitant)
  if inhabitant == "sophie"
    puts 'gender: female'
    puts 'height: 145'
  elsif inhabitant == "paul"
    puts 'gender: male'
    puts 'height: 145'
  elsif inhabitant == "dawn"
    puts 'gender: female'
    puts 'height: 170'
  elsif inhabitant == "brian"
    puts 'gender: male'
    puts 'height: 180'
  else
    puts 'species: Trachemys scripta elegans'
    puts 'height: 6'
  end
end

Обратите внимание, что ни один из операторов elsif не может быть "преобразован" в else if чистым способом.

UPDATE. Благодаря Stefan вы все равно можете использовать else if, что приводит к очень вложенному методу.

https://gist.github.com/sos4nt/a41b36d21f6eec5e0a42

Ответ 3

Я бы предпочел elsif над else if. Но это только мое мнение и технически нет никакой разницы.

Но я бы предложил использовать блок case вместо нескольких elsif вашего примера:

def describe(inhabitant)
  case inhabitant
  when "sophie"
    puts 'gender: female'
    puts 'height: 145'
  when "paul"
    puts 'gender: male'
    puts 'height: 145'
  when "dawn"
    puts 'gender: female'
    puts 'height: 170'
  when "brian"
    puts 'gender: male'
    puts 'height: 180'
  else
    puts 'species: Trachemys scripta elegans'
    puts 'height: 6'
  end

Или я бы сохранил это отображение в хеше:

PEOPLE = {
  'sophie' => { :gender => :female, :height => 145 },
  'paul'   => { :gender => :male,   :height => 145 },
  # ...
}

def describe(inhabitant)
  description = PEOPLE.fetch(
    inhabitant, { :species => 'Trachemys scripta elegans', :height => 6 }
  )

  puts "gender: #{description[:gender]}"    if description[:gender]
  puts "species: #{description[:species]}"  if description[:species]
  puts "height: #{description[:height]}"
end 

Ответ 4

Вы должны выбрать опцию, которая приведет к получению более читаемого кода. Ниже приводится пример кода, где я склонен считать, что использование else if более читаемо.

result = "Unknown"
error_code = 911

#  Version 1 - uses else if
if result == "Success"
    puts "Good job!"
else
    if error_code == "100"
        puts "No worries, we can still recover"
    else
        puts "Hopeless case!"
    end
end


#  Version 2 - uses elsif
if result == "Success"
    puts "Good job!"
elsif result != "Success" and error_code == "100"
    puts "No worries, we can still recover"
else
    puts "Hopeless case!"
end

Мое предположение - это что-то сделать с Уровень абстракции. Если все условия в if-elsif-else-end находятся на одном уровне, то это будет более читаемым. Если они находятся на разных уровнях, может оказаться полезным использовать в коде несколько else if.