我要解决这个问题。从测试中我以为我必须初始化类,但是看着解决方案我在想错误的方式。现在,我几乎了解了解决方案中的所有代码,但是我不理解的是吸气剂背后的逻辑。首先,我会写attr_accessor:title,因为最后我们写了标题,但可能会错了。其次,我不了解的事实是,我相信每次在类上调用新方法时,都必须使用初始化和分配属性的方法来实例化它。我不明白的第三件事是这行代码def title =(new_title)。我们在这里到底在做什么?我们是否正在这样做,否则以下代码将无法正常工作?谢谢。
@book.title = "inferno"
这是rake文件:
# # Book Titles
#
# # Topics
#
# * classes and objects
# * instance variables
# * setter methods
# * strings
#
# # Notes
#
# Book Titles in English obey some strange capitalization rules. For example, "and" is lowercase in "War and Peace". This test attempts to make sense of some of those rules.
#
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
specify 'prepositions' do
@book.title = "love in the time of cholera"
expect(@book.title).to eq("Love in the Time of Cholera")
end
end
describe 'should always capitalize...' do
specify 'I' do
@book.title = "what i wish i knew when i was 20"
expect(@book.title).to eq("What I Wish I Knew When I Was 20")
end
specify 'the first word' do
@book.title = "the man in the iron mask"
expect(@book.title).to eq("The Man in the Iron Mask")
end
end
end
end
及其提供的解决方案:
class Book
attr_reader :title
def title=(new_title)
words = new_title.split(" ")
words = [words[0].capitalize] +
words[1..-1].map do |word|
little_words = %w{a an and the in of}
if little_words.include? word
word
else
word.capitalize
end
end
@title = words.join(" ")
end
end
答案 0 :(得分:3)
首先,您需要了解有关访问器的概念。许多语言可以直接访问实例变量。 Ruby没有;它认为类外部的所有内容都应单独通过方法。因此,为了从外部读取或写入@title
,请使用访问器。
attr_accessor
是一种便捷方法,它定义了两种方法:属性读取器和属性写入器。当您说attr_accessor :title
时,它等同于
def title()
@title
end
def title=(value)
@title = value
end
其中title
和title=
是方法名称,而value
是title=
方法的参数。完成后,您可以编写
book.title=("New title")
puts book.title()
调用设置程序,然后调用getter。 Ruby在这里为我们提供了一些便利,因为这些是等效的语法糖:
book.title = "New title"
puts book.title
我们希望所有方法都通过方法的原因是,我们可以自定义方法。如果我们需要确保我们被允许阅读,或者如果我们想要设置的副作用,我们可以切换出一个accessor方法。但是,如果这样做,则不需要自动生成的访问器-我们将编写自己的访问器。
首先,我会写attr_accessor:title,因为最后我们写了标题,但可能会错了。
阅读器与默认阅读器相同。但是该解决方案希望创建一个自定义编写器,因此我们将自己定义它。因此,只有阅读器需要自动生成:attr_reader :title
。
第二,我不完全了解的事实是,我相信每次我们在类上调用新方法时,都必须使用初始化和分配属性的方法来实例化它。
有一个隐式的空initialize
,它继承了每个不覆盖它的类。它不带参数,什么也不做,几乎是这样的:
def initialize()
end
如果您没有编写自己的initialize
方法,则该方法正在使用。由于规范中所述的Book
不接受new
的参数,并且所有与标题的交互都通过属性访问器进行,因此您只需要使用默认的空initialize
我不明白的第三件事是这行代码def title =(new_title)。我们在这里到底在做什么?我们是否正在这样做,否则以下代码将无法正常工作?
如上所述,def title=(new_title)
与def factorial(n)
的语法完全相同,只是方法名称很奇怪。 Ruby让方法以许多非常规的方式结束:带有问号以表示布尔结果,例如equal?
,带有感叹号以表示危险操作,例如sort!
,或带有等号以允许替代调用如上所述伪装成赋值的语法。