patternMinor
Scripts loading Scripts Dynamically in Lua
Viewed 0 times
scriptsdynamicallyloadinglua
Problem
I have been working with Lua lately and I have discovered that it is capable of doing some very interesting things. I have created a proof of concept that allows one Lua script to load another Lua script and use the loaded script to modify itself by passing itself as an argument to the creation function of the loaded script. The basic example here is from a simple card game.
In this specific example, I have a Card "object" which is really just a LuaTable. At the top of the Player.lua script I have:
Then I create a card "object" by calling:
The Card.lua script loaded by
Card.lua
Here is the sample script being loaded:
SampleScript02.lua
```
SampleScript02 = {} -- the table representing the class, which will double as the metatable for the ins
In this specific example, I have a Card "object" which is really just a LuaTable. At the top of the Player.lua script I have:
local card = require "Card"Then I create a card "object" by calling:
function Player:addSpecificCardToDeck(cardSuit, cardType, cardId)
table.insert(self.deck, card:new(cardSuit, cardType, cardId))
endThe Card.lua script loaded by
require contains code that loads another script during its creation. Here is the Card.lua script. Please ignore cardSuit in this example as that code is incomplete and I have omitted it.Card.lua
Card = {} -- the table representing the class, which will double as the metatable for the instances
Card.__index = Card -- failed table lookups on the instances should fallback to the class table, to get methods
local cardList = require "Cardlist"
-- syntax equivalent to "MyClass.new = function..."
function Card:new(cardSuit, cardType, cardId)
local self = setmetatable({}, Card)
self.id = cardId
self.type = cardType
--this is where another script is loaded
print(self.id .. " cardID")
--getAbilityScriptsForId returns the appropriate string
self.testScript = require (cardList:getAbilityScriptsForId(2)) --2 is the proof of concept script being called
test = self.testScript:new(self)
test:increaseCardId()
print(self.id.. " new cardID") --the cardID will have increased by 1
return self
end
return CardHere is the sample script being loaded:
SampleScript02.lua
```
SampleScript02 = {} -- the table representing the class, which will double as the metatable for the ins
Solution
On the first line,
Having
You declare the function as
The same things apply to your second block of code.
Card = {} should be local Card = {}, otherwise Card becomes a global, breaking encapsulation. You might want to consider using strict.lua or another method of "locking" the global table to prevent mistakes like this.Having
Card double as the metatable for card instances is pretty unusual. It will work, but now Card and each of its instances are polluted with an __index property, and this could be avoided simply by writing setmetatable({}, { __index = Card }) instead of setmetatable({}, Card), which is probably what people would expect to see anyway.You declare the function as
Card:new; it has an implicit self argument because of the colon. But you never use that argument; instead, you shadow it with a local variable named self. You probably wanted to do something like local instance = setmetatable({}, self), although as mentioned it would probably be better not to have Card double as the metatable for instances, so instead you could use local instance = setmetatable({}, { __index = self }).local Card = {}
function Card:new(cardSuit, cardType, cardId)
local instance = setmetatable({}, { __index = self })
instance.id = cardId
instance.type = cardType
-- ...
return instance
end
return CardThe same things apply to your second block of code.
Code Snippets
local Card = {}
function Card:new(cardSuit, cardType, cardId)
local instance = setmetatable({}, { __index = self })
instance.id = cardId
instance.type = cardType
-- ...
return instance
end
return CardContext
StackExchange Code Review Q#60667, answer score: 5
Revisions (0)
No revisions yet.