Ruby — использовать заглавные буквы с использованием методов карты и заглавных букв

Я работаю над основами Ruby в The Odin Projects и полностью застрял на 05_book_titles. Название должно быть написано с заглавной буквы, включая 1-е слово, но не включая «маленькие слова» (например, «кому», «то» и т. д.), ЕСЛИ это не 1-е слово. Я не могу заставить код делать что-либо, кроме как использовать все заглавные буквы. Я неправильно использую метод карты? Как я могу заставить его включать слова no_cap в возвращаемый заголовок без использования заглавных букв?

Рубиновый файл:

class Book
def title
    @title
end 

def title=(title)
    no_cap = ["if", "or", "in", "a", "and", "the", "of", "to"]
    p new_title = @title.split(" ")
    p new_new_title = new_title.map{|i| i.capitalize if !no_cap.include? i}
.join(" ") 
end
end

Некоторые из файлов спецификации:

require 'book'

describe Book do

  before do
    @book = Book.new
  end

  describe 'title' do
    it 'should capitalize the first letter' do
      @book.title = "inferno"
      expect(@book.title).to eq("Inferno")
    end

    it 'should capitalize every word' do
      @book.title = "stuart little"
      expect(@book.title).to eq("Stuart Little")
    end

    describe 'should capitalize every word except...' do
      describe 'articles' do
        specify 'the' do
          @book.title = "alexander the great"
          expect(@book.title).to eq("Alexander the Great")
        end

        specify 'a' do
          @book.title = "to kill a mockingbird"
          expect(@book.title).to eq("To Kill a Mockingbird")
        end

        specify 'an' do
          @book.title = "to eat an apple a day"
          expect(@book.title).to eq("To Eat an Apple a Day")
        end
      end

      specify 'conjunctions' do
        @book.title = "war and peace"
        expect(@book.title).to eq("War and Peace")
      end
    end
  end
end

Результат:

Book
  title
    should capitalize the first letter (FAILED - 1)

Failures:

  1) Book title should capitalize the first letter
     Failure/Error: @book.title = "inferno"

     NoMethodError:
       undefined method `split' for nil:NilClass
     # ./05_book_titles/book.rb:8:in `title='
     # ./05_book_titles/book_titles_spec.rb:25:in `block (3 levels) in <top (required)>'

Finished in 0.0015 seconds (files took 0.28653 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./05_book_titles/book_titles_spec.rb:24 # Book title should capitalize the first letter

person Mo102    schedule 03.11.2019    source источник


Ответы (2)


Вы используете @title до того, как он назначен в

new_title = @title.split(" ")

Его следует изменить на title.

Вы не присваиваете рассчитанный заголовок @title в конце метода title=.

Вам также нужно добавить «an» к no_cap, чтобы пройти спецификацию, используя в качестве заголовка «есть яблоко в день».

И позаботьтесь о первом слове:

class Book
  def title
      @title
  end 

  def title=(title)
      no_cap = ["if", "or", "in", "a", "and", 'an', "the", "of", "to"]
      new_title = title.split(' ').each_with_index.map do |x, i|
          unless i != 0 && no_cap.include?(x)
            x.capitalize
          else
            x
          end
      end

      @title = new_title.join(' ')
  end
end
person luis.parravicini    schedule 03.11.2019
comment
Примечание: "My dog has ______fleas.".split(' ').join(' ') #=> "My dog has fleas.", где символы подчеркивания представляют собой дополнительные пробелы (которые, если бы они были пробелами, были бы удалены SO). - person Cary Swoveland; 04.11.2019
comment
@CarySwoveland да, но я не знаю, будет ли это проблемой. - person luis.parravicini; 04.11.2019

small_words = [если, или, в, а, и, из, в]

str = "tO be      Or Not to be."

str.gsub(/\p{Alpha}+/) { |s| Regexp.last_match.begin(0) > 0 &&
  small_words.include?(s.downcase) ? s.downcase : s.capitalize }
  #=> "To Be      or Not to Be."
person Cary Swoveland    schedule 04.11.2019
comment
это очень-очень small_words между прочим! - person ronnie bermejo; 04.11.2019
comment
Согласно стилю AP, список слов, которые не пишутся с заглавной буквы, — это a, an, and, at, but, by, for, in, nor, of, on или, out, so, the, to , вверх и еще. (If не является одним из них.) Кроме того, at, by, for, in, of, out, so, to, up и пока не пишутся с заглавной буквы, когда используются как предлоги, но пишутся с большой буквы, когда используются как наречия, например. Джо открывает дверь, Клемсон еще не проиграл, Джилл ищет друга и т. д. Таким образом, решение сложнее, чем это если ОП не упрощает правила, и в этом случае ему может потребоваться более четко изложить свои правила. - person BobRodes; 05.11.2019
comment
@ Боб, хм. Больше, чем небольшая поправка, чтобы определить, используется ли короткое слово в качестве наречия, но я сомневаюсь, что это цель упражнения. Я ожидаю, что многим читателям будет трудно объяснить, что такое наречие. Я научился этому в 6-м классе, рисуя предложения в виде диаграмм. - person Cary Swoveland; 05.11.2019
comment
@CarySwoveland Я тоже в этом сомневаюсь, потому что это, безусловно, нетривиально и скорее крайний случай проблемы правильного использования заглавных букв в заголовках. Но я подумал, что это стоит упомянуть, так как мы, люди, склонны верить, что решили более широкую проблему, чем мы на самом деле решили, решая подмножество проблемы. - person BobRodes; 08.11.2019