Ruby类变量实例变量错误



Game有一个由十个Frame实例组成的数组

class Frame
attr_accessor :rolls
def initialize
@rolls = ""
end

end
class Game
attr_accessor :frames
def initialize
@frames = Array.new(10, Frame.new) 
end

def print_frames
@frames.each_with_index do |frame, idx|
p "Frame ##{idx+1}: #{frame.rolls}"
end
end
end
game = Game.new
rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2]
curr = 0
rolls.each_with_index do |roll|
game.frames[curr].rolls << roll.to_s
if game.frames[curr].rolls.size == 2
curr += 1
end
end
p "Total rolls: #{rolls.size}"
p game.print_frames

我预计要打印10行,每行都有一个由2个数字组成的框架id但是,以下是返回的

"Total rolls: 20"
"Frame #1: 55374000000000000022"
"Frame #2: 55374000000000000022"
"Frame #3: 55374000000000000022"
"Frame #4: 55374000000000000022"
"Frame #5: 55374000000000000022"
"Frame #6: 55374000000000000022"
"Frame #7: 55374000000000000022"
"Frame #8: 55374000000000000022"
"Frame #9: 55374000000000000022"
"Frame #10: 55374000000000000022"
[#<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">, #<Frame:0x0000565402e40528 @rolls="55374000000000000022">]

实例变量的作用类似于框架之间共享的类变量。所有20个卷号都被连接起来,而不是每个帧都拥有一对
代码出了什么问题?是因为GameFrame对象没有正确实例化吗?

Array.new(10, Frame.new)

创建一个包含10个元素的数组,所有元素都指向一个Frame实例。要创建一个包含10个独立Frame实例的数组,您应该使用块形式。

Array.new(10) { Frame.new }

这执行块10次,并将每次执行的结果分配给共同发起索引。

请参阅:创建阵列

也可以通过显式调用零的CCD_ 7来创建数组,一个(Array的初始大小(或两个参数(初始大小以及默认对象(。

ary = Array.new    #=> []
Array.new(3)       #=> [nil, nil, nil]
Array.new(3, true) #=> [true, true, true]

请注意,第二个参数使用对的引用填充数组相同的对象因此,只有在您需要使用本机不可变对象实例化数组,例如符号、数字,真或假。

要创建具有单独对象的阵列,可以传递块相反此方法可以安全地与诸如散列、字符串或其他数组:

Array.new(4) {Hash.new}    #=> [{}, {}, {}, {}]
Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
方法Array.new被定义为new(size=0,default=nil(,这意味着第二个参数将是数组中所有对象的值,默认值。

这就是为什么对于您的案例,所有10个对象都是相同的。

https://ruby-doc.org/core-2.7.0/Array.html#method-c-new

这个代码段可以帮助你解决

@frames = []
10.times {|i| @frames.push(rand) }
=> [0.7053319996471655, 0.34131818323294594, 0.4084836724883256, 0.20452172335941388, 0.5124065818560665, 0.4203474973940552, 0.6719502264788891, 0.7453268015406016, 0.09500886225101768, 0.9053707563920769]
# try this for your case
# 10.times {|i| @frames.push(Frame.new) } 
# using array creation with block
# ty tadman for the advice
# @frames = Array.new(10) { Frame.new }

最新更新