以下内容来自The Rspec Book。我想知道为什么messages << message
中的def puts
不是@messages << message
。我理解||= []
是memoization,我也理解@messages
是一个实例变量。那么,它应该在同一个类中使用吗?或者这是一个错字?
class Output
def messages
@messages ||= []
end
def puts(message)
messages << message
end
end
def output
@output ||= Output.new
end
Given /^I am not yet playing$/ do
end
When /^I start a new game$/ do
game = Codebreaker::Game.new(output)
game.start
end
Then /^I should see "([^"]*)"$/ do |message|
output.messages.should include(message)
end
答案 0 :(得分:5)
由于
def puts(message)
messages << message
end
然后调用
def messages
@messages ||= []
end
||= []
将空数组分配给@messages
(如果它尚不存在)。这就是puts(message)
不直接使用@messages
的原因。
编辑:
如果您直接@messages << message
,则@messages
可能尚未存在。这就是你改为messages
的原因。
答案 1 :(得分:5)
我认为您的混淆在@messages
变量和messages
方法
class Output
def messages
@messages ||= []
end
def puts(message)
messages << message #=> here `messages` refer to the method above
end
end
这是一个简单的例子
class Output
def m
@messages ||= []
end
def puts(message)
m << message #=> method `m`
end
end
v = Output.new
v.puts "blah"
v.m #=> ["blah"]
示例2(为了更加清晰)
class Output
def m
@messages ||= []
end
def puts(message)
m << message #=> here `m` refer to the method above
end
def show_at_messages_variable
@messages
end
end
v = Output.new
v.puts "blah"
v.show_at_messages_variable #=> ["blah"]
答案 2 :(得分:5)
作者选择了懒惰的对象创建, 消息不是在构造函数中创建的,而是在getter方法中创建的。 只要你不直接访问@messages就不能得到零例外。
class Output
def messages
@messages ||= []
end
def puts(message)
# If i was to use the variable @messages at this point,
# i would get a nil exception, the array was never allocated.
# Using the getter ensures that the array is allocated.
messages << message
end
end
如果你有一个明显的不需要懒惰创建对象,你可以用以下方式编写同一个类。
class Output
attr_reader :messages
def initialize(message)
@messages = []
end
def puts(message)
# messages was created when this object was initialized,
# thus it is perfectly safe to use here.
@messages << message
end
end