The second parameter of CreateFrame is the name, which I assume you wanted to be named CommandStartStop. Try this:
function CreateSquare(squareName, x, y, colour)
local myFrame = CreateFrame("Frame", squareName, UIParent)
myFrame:SetFrameStrata("BACKGROUND")
myFrame:SetWidth(5)
myFrame:SetHeight(5)
myFrame.texture = myFrame:CreateTexture(nil,"BACKGROUND")
myFrame.texture:SetAllPoints(myFrame)
myFrame:SetPoint("TOPLEFT",x,y)
myFrame:Show()
myFrame.texture:SetColorTexture(colour[1], colour[2], colour[3])
end
As an aside, these names that aren’t local (named frames, the function CreateSquare) share the same namespace as all other addons and the default UI itself. Globals aren’t inherently bad, just take care to make them uniquely named.
Also if you did want an anonymous frame and reference it by a variable, a small adjustment to your “factory” function:
local function CreateSquare(x, y, colour)
local myFrame = CreateFrame("Frame", nil, UIParent)
myFrame:SetFrameStrata("BACKGROUND")
myFrame:SetWidth(5)
myFrame:SetHeight(5)
myFrame.texture = myFrame:CreateTexture(nil,"BACKGROUND")
myFrame.texture:SetAllPoints(myFrame)
myFrame:SetPoint("TOPLEFT",x,y)
myFrame:Show()
myFrame.texture:SetColorTexture(colour[1], colour[2], colour[3])
return myFrame
end
Now you can do things like:
local myFrames = {}
for i=1,10 do
myFrames[i] = CreateSquare(i*10+300,-(i-1)*10-300,{1,0,0})
end
Note the function is local too so it will only exist in the scope of the current file it’s in. You can make it global or a member of your addon’s namespace. Again, creating named frames is totally fine; and it’s nice to be able to /fstack to see what addon is putting them on the screen–if they include the addon name in their name–but since these are tiny 5x5 I expect you’ll be making lots.