Search code examples
randomluametatable

Random number generation problem with meta table


Please look at the next code, Lua.

randomNumber = {
  new = function(self,o)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  return o
  end,

  math.randomseed(os.time()),
  
  getNum = math.random()
}

for i = 1, 10 do
  x = randomNumber:new()
  print(x.getNum)
end

The output results are as follows.

0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248

I want to get 10 different numbers. Can someone help me? Thank you in advance.


Solution

  • Let's take a look at your table constructor

    randomNumber = {
      new = function(self,o)  -- this assigns a function to randomNumber["new"]
      o = o or {}             -- that will return a new instance of your class
      setmetatable(o, self)
      self.__index = self
      return o
      end,
    
      math.randomseed(os.time()), -- this assigns the first of two random seed components
                                  -- returned by math.randomseed to randomNumber[1]
      
      getNum = math.random()    -- this assings a random number [0,1) to randomNumber["getNum"]
    }
    

    In the loop

    for i = 1, 10 do
      x = randomNumber:new()
      print(x.getNum)
    end
    

    You create a new instance named x of randomNumber 10 times. You then print x.getNum.

    x.getNum is a nil value so Lua will check wether x has a metatable with a __index field. __index refers to randomNumber so Lua will print randomNumber.getNum which is the random number [0,1) which has not changed since we constructed randomNumber.

    You need to call math.random every time you want a new random number.

    If you want each instance of randomNumber to be constructed with a random number you need to assign o.rn = math.random() in your new function and either access it via x.rn later or add a function getNum to randomNumber.

    getNum = function (self) return self.rn end`
    

    so you can print(x:getNum())

    I'm not sure if this is more than a exercise with metatables. But having a dedicated class that just holds a single number doesn't make too much sense to me. Just use a number value.