Ruby attr_accessor not being read
-
23-03-2021 - |
Question
I am developing a game with Ruby using the Gosu
and Chipmunk
gems. I have the following class in the file named HeroBullets.rb
:
require 'gosu'
class HeroBullets
attr_accessor :y
def initialize(window)
@x = 20
@y = 0
end
end
I know need to access this class from another file, Physics.rb
which handles all the Chipmunk
code.
At the top I have:
require 'chipmunk'
load 'HeroBullets.rb'
class Physics
attr_accessor :play_area
def initialize(window)
@hBullets = Array.new(25)
@hBullets << HeroBullets.new(window)
@hBullets << HeroBullets.new(window)
end
And further down there is:
def fire_arrow(y)
for i in 0...@hBullets.count
@bullet = @hBullets[i]
if(@bullet.y == y)
@hBullets[i].active = true
end
end
end
The Error I get is:
Physics.rb:112:in block in fire_arrow': undefined methody' for nil:NilClass
(NoMethodError) from Physics.rb:110:in each' from Physics.rb:110:infire_arrow'
from FileManager.rb:90:in fireHero' from .../lib/main.rb:90:inupdate' from .../lib/main.rb:129:in `'
Solution
The problem is that if @hBullets
has 10 elements, @hBullets.count
will output 10
, but @hBullets[10]
does not work, because the index of an array starts at 0
not at 1
. The tenth element will be in @hBullets[9]
. You get the error message because the element you are trying to access is nil
, not because "attr_accessor is not being read".
That being said, Ruby offers much easier ways to iterate over an array. I would rewrite your code like this:
def fire_arrow(y)
@hBullets.each do |bullet|
bullet.active = true if bullet.y == y
end
end
Another problem with your code is that you initialize a new array like this:
@hBullets = Array.new(25)
This creates an array with 25 elements that are all nil
. You should start with an empty array instead:
@hBullets = Array.new
Or:
@hBullets = []