Search code examples
functionluacomputercraft

For loop inside a function in Lua, Computercraft


I'm learning programming in computercraft (minecraft) and having some trouble with reading some storage cells.

The function that I'm working on shall go through all cells and add together the storage capacity to a variable in a for loop.

This is what I got so far

local cell1 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_2")
local cell2 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_3")
local cell3 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_4")
local cell4 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_5")
local cell5 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_6")
local cell6 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_7")

cells = {"cell1", "cell2", "cell3", "cell4", "cell5", "cell6"}

local totStorage

function getTotStorage(table)
    for key = 1,6 do
        x = table[key]
        totStorage = totStorage + x.getMaxEnergyStored()        
    end
    print(totStorage)
end

I get an error on this line

totStorage = totStorage + x.getMaxEnergyStored()    

saying "Attempt to call nil". Any suggestions?


Solution

  • cells = {"cell1", "cell2", "cell3", "cell4", "cell5", "cell6"}
    

    Is shorthand for:

    cells = {
    -- key   value
       [1] = "cell1", 
       [2] = "cell2", 
       [3] = "cell3", 
       [4] = "cell4", 
       [5] = "cell5", 
       [6] = "cell6"
    }
    

    Assuming that your getTotStorage call is similar to below (you didn't post it)

    getTotStorage(cells)
    

    In the loop you try to call a method on x which is a string value:

    for key = 1,6 do
       x = table[key]
       totStorage = totStorage + x.getMaxEnergyStored()        
    end
    

    This is essentially trying to do:

    totStorage = totStorage + ("cell1").getMaxEnergyStored()
    

    What you could do is rearrange your code so that the values are the objects returned by peripheral.wrap:

    local cells = {
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_2"),
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_3"),
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_4"),
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_5"),
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_6"),
      peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_7"),
    }
    
    function getTotStorage(t)
      local totStorage = 0
      for i,v in ipairs(t) do
         totStorage = totStorage + v.getMaxEnergyStored()
      end
      print(totStorage)
    end
    

    A few observations:

    • Use local when you can (i.e. totStorage) to limit the scope of a variable (no need to have a loop counter as a global)
    • Don't name variables that collide with the standard Lua library (i.e. string, table, math)
    • ipairs is a better way to loop through a sequence