Пытаюсь понять, как эти операторы if else закрываются правильно

#ruby

#рубиновый #ruby

Вопрос:

 # A name is valid is if satisfies all of the following:
# - contains at least a first name and last name, separated by spaces
# - each part of the name should be capitalized


def is_valid_name(str) 
word_Split = str.split(" ")
if word_Split.length >= 2 
word_Split.each do |x| 
  if x == x.capitalize
  else 
      return false
  end
end
return true
end
return false
end

puts is_valid_name("Kush Patel") # => true
puts is_valid_name("Daniel") # => false
puts is_valid_name("Robert Downey Jr") # => true
puts is_valid_name("ROBERT DOWNEY JR") # => false
  

В приведенном выше коде я понимаю размещение первого оператора if / else . У меня возникают проблемы с пониманием, сделайте 2 конца под первым возвращаемым значением false, закройте .каждый цикл и метод?

Что вообще делают return true и return false вне цикла? Я пытаюсь понять, чтобы прочитать этот код.

Поскольку я все еще новичок в программировании, я писал операторы if / else следующим образом: если это, сделай это. в противном случае, сделайте это. или используйте elsif между ними.

Я ценю любую помощь в понимании того, как это читается. Я взглянул на операторы if / else на c , и их было немного легче читать. Используя { }, чтобы разделить их. Спасибо за ваше терпение и понимание.

Комментарии:

1. Попробуйте последовательно делать отступы в коде, и должно быть более очевидно, что end соответствует чему.

2. Рекомендуется, чтобы имена переменных и методов записывались в регистре snake . Например, word_split вместо word_Split or wordSplit . Вам не обязательно это делать, но 99% Rubyists делают.

Ответ №1:

Первое, что я бы сделал, это взял код, исправил отступ и добавил новые строки, где это полезно для повышения удобочитаемости. Затем я добавил встроенные комментарии, чтобы немного объяснить, что происходит.

 def is_valid_name(str) 
  word_Split = str.split(" ")

  # at least two words?
  if word_Split.length >= 2 
    word_Split.each do |x| 
      # This if block is empty and control falls through to [1]
      # once all the words in the loop pass the check. This if/else
      # could be replaced by `unless`
      if x == x.capitalize
        
      else
        # Immediately exit the function and return false since
        # a single word in the loop was not capitalized
        return false
      end
    end

    # [1] This handles the case where 
    # each word had a proper first letter capitalized
    return true
  end
  
  # There was zero or one word, return false. 
  # Technically in ruby, the word `return` is optional
  # for the last line in the method
  return false 
end
  

В приведенном выше коде я понимаю размещение первого оператора if / else . У меня возникают проблемы с пониманием, сделайте 2 конца под первым возвращаемым значением false, закройте .каждый цикл и метод?

Нет. Два end сразу после первого return false закрывают if/else оператор, затем цикл. Два следующих ends закрывают первый if оператор, а затем метод.

Что вообще делают return true и return false вне цикла? Я пытаюсь понять, чтобы прочитать этот код.

return true Обрабатывает регистр, все слова (по крайней мере, 2 или более) начинаются с заглавной буквы. return false Обрабатывает случай, когда после попытки разделения остается только ноль или одно слово.

Как бывший разработчик C / C , я рекомендую вам посмотреть на условные выражения Ruby как хороший момент для продолжения чтения. В частности, изучите, if, else, elsif, and unless а также завершающие условные выражения.

Комментарии:

1. Спасибо Мэтью, что нашел время для этого. Я изо всех сил пытался научиться писать код. Переход от творческой области к чему-то подобному. Спасибо. Я подробнее расскажу о if, else, elsif и unless и завершающих условных обозначениях.

2. @MildManneredMan приятно слышать, продолжайте в том же духе! Переключение полей — это очень полезный путь к росту.

Ответ №2:

Я думаю, что Мэтью уже дал отличные ответы на ваши вопросы.

Изучение нового языка непросто, особенно потому, что вам нужно не только понимать различный синтаксис и различные концепции, но и ознакомиться с распространенными идиомами и распространенными стилями кодирования.

Сообщество Ruby, например, использует имена переменных с подчеркиванием, предпочитает, чтобы имена методов заканчивались вопросительным знаком, когда метод возвращает логическое значение, и из-за неявных возвратов во многих случаях избегает использования явных возвращаемых значений.

Тем не менее, я согласен с тем, что пример кода в вашем вопросе трудно понять. В основном по той причине, что он не соответствует общим идиомам Ruby и рекомендациям.

В качестве примера я хотел бы показать переработанную версию, которая ведет себя точно так же, и что ИМХО выглядит более рубиновым:

 def valid_name?(name) 
  parts = name.split

  parts.size >= 2 amp;amp; 
    parts.all? { |part| part == part.capitalize }
end

valid_name?("Kush Patel") # => true
valid_name?("Daniel") # => false
valid_name?("Robert Downey Jr") # => true
valid_name?("ROBERT DOWNEY JR") # => false
  

Комментарии:

1. Это было намного легче читать. Спасибо. Я склонен чувствовать себя немного глупо, изучая что-то новое, подобное этому. Но это не помешало мне попробовать. Спасибо, что также нашли время для ответа!

Ответ №3:

Для этого вы можете использовать регулярное выражение.

 def valid_name?(name)
  name.match? /A(?:p{Upper}p{Lower} )(?:  p{Upper}p{Lower} ) z/
end
  
 valid_name?("Kush Patel")        #=> true
valid_name?("Cher")              #=> false
valid_name?("Robert Downey Jr")  #=> true
valid_name?("ROBERT DOWNEY JR")  #=> false
  

См. Строку #match?.

Регулярное выражение можно сделать самодокументируемым, записав его в режиме свободного пробела.

 /A            # match beginning of string
 (?:           # begin a non-capture group
   p{Upper}   # match an upper-case Unicode letter
   p{Lower}   # match one or more lower-case Unicode letters
 )             # end non-capture group
 (?:           # begin a non-capture group
              # match one or more spaces
   p{Upper}   # match an upper-case Unicode letter
   p{Lower}   # match one or more lower-case Unicode letters
 )             # end non-capture group and execute it one or more times
 z            # match end of string
 /x            # employ free-spacing regex definition mode 
  

p{Upper} ( p{Lower} ) может быть альтернативно записано p{Lu} ( p{Ll} ) или [[:upper:]] ( [[:lower:]] ) . Если ASCII удовлетворительный, можно использовать [A-Z] ( [a-z] ) . Смотрите Регулярное выражение.

Обратите внимание, что я использовал ..(?: p{Upper}p{Lower} ).. в определении метода и ..(?: p{Upper}p{Lower} ).. при выражении регулярного выражения в режиме свободного пробела (в последнем символ пробела экранируется). Это потому, что режим свободного пробела удаляет все пробелы перед анализом выражения. Чтобы сохранить пробелы, они должны быть экранированы, помещены в символьный класс ( [ ] ) или заменены на p{Zs} . Я бы посоветовал не писать s , [[:space:]] и p{Space} поскольку они также соответствуют символам новой строки ( n ), что в некоторых случаях может быть проблематичным.