2014-02-17 150 views
17

我試圖用紅寶石製作康威的生活遊戲版本。我用@play_area創建了一個Grid類作爲實例變量。但是,當我運行我的代碼時,@play_area在它已經被兩次評估後變爲零(當在@play_area [x_mod] [y_mod] .alive中對行進行評估時)。這是爲什麼發生?Ruby未定義方法`[]'爲零:NilClass(NoMethodError)

EDIT

這裏的初始化功能:

def initialize(sizex, sizey) 
    @x_length = sizex 
    @y_length = sizey 
    @play_area = [] 
    #initialize dead cells 
    @x_length.times do |x| 
     @play_area[x] ||= [] 
     @y_length.times do |y| 
      @play_area[x][y] = Cell.new(x, y, false) 
      puts @play_area[x][y].inspect 
     end 
    end 
end 

下面是在發生錯誤的功能:

def neighbor_num_of_cell(pos_x,pos_y) 
    c = @play_area[pos_x][pos_y] 
    count = 0 
    ((pos_x-1)..(pos_x+1)).each do |x| 
     ((pos_y-1)..(pos_y+1)).each do |y| 
      unless @play_area[x][y].eql?(c) 
       x_mod = x % (@x_length + 1) 
       y_mod = y % (@y_length + 1) 
       puts x_mod 
       puts y_mod 
       if @play_area[x_mod][y_mod].alive 
        count += 1 
       end 
      end 
     end 
    end 
    count 
end 

在每個細胞的檢查中@play_area表明每個單元格都被正確初始化,這裏是檢查的輸出:

[email protected]:~/programs/ruby$ ruby main.rb 
#<Cell:0x00000000f919d8 @alive=false, @alive_next=false, @x_pos=0, @y_pos=0> 
#<Cell:0x00000000f91848 @alive=false, @alive_next=false, @x_pos=0, @y_pos=1> 
#<Cell:0x00000000f916e0 @alive=false, @alive_next=false, @x_pos=0, @y_pos=2> 
#<Cell:0x00000000f915a0 @alive=false, @alive_next=false, @x_pos=0, @y_pos=3> 
#<Cell:0x00000000f91460 @alive=false, @alive_next=false, @x_pos=0, @y_pos=4> 
#<Cell:0x00000000f91320 @alive=false, @alive_next=false, @x_pos=0, @y_pos=5> 
#<Cell:0x00000000f911e0 @alive=false, @alive_next=false, @x_pos=0, @y_pos=6> 
#<Cell:0x00000000f910a0 @alive=false, @alive_next=false, @x_pos=0, @y_pos=7> 
#<Cell:0x00000000f90f38 @alive=false, @alive_next=false, @x_pos=0, @y_pos=8> 

...

#<Cell:0x00000000f1abf8 @alive=false, @alive_next=false, @x_pos=19, @y_pos=7> 
#<Cell:0x00000000f1aa90 @alive=false, @alive_next=false, @x_pos=19, @y_pos=8> 
#<Cell:0x00000000f1a900 @alive=false, @alive_next=false, @x_pos=19, @y_pos=9> 
#<Cell:0x00000000f1a798 @alive=false, @alive_next=false, @x_pos=19, @y_pos=10> 
#<Cell:0x00000000f1a658 @alive=false, @alive_next=false, @x_pos=19, @y_pos=11> 
#<Cell:0x00000000f1a518 @alive=false, @alive_next=false, @x_pos=19, @y_pos=12> 
#<Cell:0x00000000f1a3b0 @alive=false, @alive_next=false, @x_pos=19, @y_pos=13> 
#<Cell:0x00000000f1a270 @alive=false, @alive_next=false, @x_pos=19, @y_pos=14> 
#<Cell:0x00000000f1a130 @alive=false, @alive_next=false, @x_pos=19, @y_pos=15> 
#<Cell:0x00000000f19ff0 @alive=false, @alive_next=false, @x_pos=19, @y_pos=16> 
#<Cell:0x00000000f19e88 @alive=false, @alive_next=false, @x_pos=19, @y_pos=17> 
#<Cell:0x00000000f19d20 @alive=false, @alive_next=false, @x_pos=19, @y_pos=18> 
#<Cell:0x00000000f19be0 @alive=false, @alive_next=false, @x_pos=19, @y_pos=19> 
+0

看起來'@play_area [pos_x]'是'nil',因此'@play_area [pos_x] [pos_y]'拋出了一個'NilClass'錯誤。 – zeantsoi

回答

4

問題是這一行:

@play_area[x][y] = Cell.new(x, y, false) 

@play_area[x]爲零。您只初始化多維數組的一個維度。在嘗試向其中添加元素之前,您需要將@play_area[x]的每個元素初始化爲數組。

@x_length.times do |x| 
    @play_area[x] ||= [] 
    @y_length.times do |y| 
    @play_area[x][y] = Cell.new(x, y, false) 
    end 
end 
+0

不幸的是,這並沒有解決問題。現在提供的代碼中的@playArea [x] || = []'會在我嘗試運行它時產生NilClass錯誤。 – steamingramen

+0

'play_area',而不是'playArea'。 – meagar

+0

謝謝@meagar,我解決了這個問題,但仍然無法正常運行。我編輯了我的OP來提供更多信息 – steamingramen

0

我以前就遇到過這個問題。你的問題來自於試圖檢查不存在的單元。想一想這個函數如何評估細胞周圍的細胞(0,0)。首先它將查看單元格的內容(-1,-1)......這是Nil。我們很幸運能夠通過Ruby獲得Nil;在Python中,這會引發'列表索引超出範圍'異常。

+1

我幾乎不滿意Python的投標。 – toszter

+0

題外話:其實並非如此。 Python中的thing [-1]是列表的最後一個元素,而不是索引超出範圍的異常(除非列表爲空,在這種情況下,thing [0]將執行相同操作) – scav

相關問題