I have been thinking about how to encourage code reuse among authors on and off since i joined this community. I have made some suggestions in the past, some of them hairbrained some of them good.
Rather than suggest a design this time though, I'd like to just start a discussion on the merits of this concept.
I'm thinking of single addon libraries, and cut-and-paste code snippets. They both can be covered by the notion of a "static library". I have to use this term since the libraries we use today are "dynamic" in the sense that they interact with other copies of themselves (upgrading).
What I am thinking of is more like how Lua itself uses "libraries" in the form of modules - you get your own copy of the code, and it doesn't change at runtime.
One of my thoughts was to just use LuaCompat to enable the Lua module system for wow using an addon. Well - the flaw in that is that you'd need to get people to install an addon to enable the internal library in your addon - or make the addon a library which goes against the grain of what I want to achieve.
LibStub may work for single use libraries, but someone might reuse your single use library without you ever knowing (it is open source after all). Plus you don't need libstub if you aren't sharing a library.
We have access to a unique table for the addon a Lua file runs in. It seems we could use that table and come up with a scheme whereby we can just drop Lua files into our code and that would give us the advantages of code reuse without the stigma of being a shared library. It would also give other authors a way to write 'utility' code without creating 'yet another library'.
I could come up with a design but maybe some of you have some ideas?
So, you're saying you want to come up with a system of "cut and paste code snippets" that anyone can just use directly by dropping the file in their addon, and that private snippet is of course standalone?
I understood it to mean that there would be shared methods, as opposed to full on libraries. But I'm not sure I got that right. Something like...
BigOleSharedCodeLibrary = GetInstanceOfBigOleSharedCodeLibrary
if BigOleSharedCodeLibrary.SomeUsefulMethodSoemoneWrote then
BigOleSharedCodeLibrary.SomeUsefulMethodSoemoneWrote()
end
Interesting. However, with the current packager behavior, it would require hard-embedding. Else the -nolib wouldn't have those files and thus would fail to load.
This kind of implies hard embedding, as it would fail on checkouts (cant load a disembed copy), and has the potential to break when grabbing a newer version, as the stable API restrictions dont necessarily have to apply.
Using LibStub doesn't really add any significant overhead, and if someone else uses your "private library", screw 'em. Unless the library is officially released, I think it's fairly clear to anyone with a brain that there's no support and no guarantee that future versions won't break compatibility. I use LibStub for "private" libraries, and a number of addons I use do the same, or roll their own shared libraries, and as far as I know nobody other than the original authors are using them. Plus, unless you specifically license the library for redistribution, you can easily stop someone from including it with addons, at least on the legitimate sites.
Furthermore, if your "private library" code is generalized enough that it's useful to more than one addon at a time, why not make it a shared library? Why have 5, 10, 50 copies of the same code loaded into memory at the same time?
Finally, what about updates? If there's a bug, then fixes aren't automatically shared with all addons using the code. Each author has to individually notice when there's an update, copy and paste the new file or code into his addon, and specifically release a new version of the addon. With shared libraries, authors don't need to deal with watching for updates, and it's not urgent to release a new version of every addon each time a library changes.
The point is there is a size/complexity threshold somewhere that says, oh its easier to just do it myself (cut/paste usually). That's one niche this stuff could occupy.
The files in tekkub's addon template are a good example. E.g. When I don't need all the bells and whistle of AceEvent-3.0, I use something similar to this (tekkub's code) :
local myname, ns = ...
local f = CreateFrame("frame")
f:SetScript("OnEvent", function(self, event, ...) if ns[event] then return ns[event](ns, event, ...) end end)
function ns:RegisterEvent(...) for i=1,select("#", ...) do f:RegisterEvent((select(i, ...))) end end
function ns:UnregisterEvent(...) for i=1,select("#", ...) do f:UnregisterEvent((select(i, ...))) end end
ns.RegisterEvents, ns.UnregisterEvents = ns.RegisterEvent, ns.UnregisterEvent
I don't use AceLocale-3.0 anymore, I often copy-paste like this:
local addonName, ns = ...
local L = setmetatable({}, {__index = function(t, k)
if k then
--@alpha@
print(addonName, "unlocalized string:", tostring(k))
--@end-alpha@
self[k] = tostring(k)
end
return tostring(k)
end})
ns.L = L
-- enUS
L["String"] = true
if GetLocale() == "frFR" then
L["String"] = "ChaƮne"
end
for k,v in pairs(L) do if v == true then L[k] = k end end
Those pieces of code barely need to be turned into libraries. Moreover, they would gain nothing or little of being libraries. One of the strength of libraries like AceTimer-3.0 or AceGUI-3.0 is to optimize resource usage, either by recycling the resources or by using smart algorithms to efficiently handle requests from the various addons.
Well, if that's all you're talking about, why are you even talking about it? While we're at it, let's start a thread to discuss the merits of having a forum. Are there any authors who don't realize they can copy and paste commonly used snippets of code?
Because not all authors start out at the same level?
This sits somewhere between using a proper library to handle common/repeated tasks
(that in some cases would be overkill and has a steeper learning curve)
vs using "templates" to do that same common/repeated tasks when you don't need all the bells and whistles.
For one it might cut down on all the "help me get started with simple addons" threads..
"There look at those templates for proper event handling, saved variables etc"
I see nothing wrong with this if these templates are good.
I don't really see the value in a template for the "help me get started" folks. There are hundreds, if not thousands, of extremely simple yet fully functional addons that can be used as examples and guides, that are much better for that purpose than an abstract "template" that doesn't actually do anything. You learn more from looking at something that actually works, and figuring out how it works, than you do from looking at some parts that don't do anything and trying to figure out how to put them together to make something that works.
I don't really see the value in a template for the "help me get started" folks. There are hundreds, if not thousands, of extremely simple yet fully functional addons that can be used as examples and guides, that are much better for that purpose than an abstract "template" that doesn't actually do anything. You learn more from looking at something that actually works, and figuring out how it works, than you do from looking at some parts that don't do anything and trying to figure out how to put them together to make something that works.
I can second Phanx on that, this is mostly how I learned making my addons
Except however, that sometimes I didn't have any idea, what any specific piece of code actually did, because of lack of documentation, or sloppy coding (even though they were very simple). They weren't meant to be for learning addons I guess..
I don't really see the value in a template for the "help me get started" folks. There are hundreds, if not thousands, of extremely simple yet fully functional addons that can be used as examples and guides, that are much better for that purpose than an abstract "template" that doesn't actually do anything. You learn more from looking at something that actually works, and figuring out how it works, than you do from looking at some parts that don't do anything and trying to figure out how to put them together to make something that works.
templates break over time and who wants to maintain non functioning code :P
also people should ask questions and join the community when they run into problems. i rather have them ask early and often rather than late with a big mess of code that nobody can read.
Don't get sidetracked by the fact that the code units im talking about just happen to be in an "addon template". Im not talking about the whole addon template, im talking about the individual files.
Using these code units is not just about "help me get started", it helps promote good program structure as well - so you just dont have 1 big blob. Also by separating out the boilerplate the main addon code is less cluttered, this physical separation helps prevent code for 1 thing getting intertwined with code from another thing.
And, as an aside. Copy/Paste doesn't help you learn anything either. Look how many addons have getglobal in them or this globals. Where do you think those came from in most cases.
Im thinking something like, a community maintained collection of 'templates' or whatever term is most appropriate which are added to through a meritocracy, ie. only those that are in use get added, and only those that are being used are part of the collection. Idk...just thinking.
The files in tekkub's addon template are a good example. E.g. When I don't need all the bells and whistle of AceEvent-3.0, I use something similar to this (tekkub's code) :
...
I don't use AceLocale-3.0 anymore, I often copy-paste like this:
...
Those pieces of code barely need to be turned into libraries. Moreover, they would gain nothing or little of being libraries. One of the strength of libraries like AceTimer-3.0 or AceGUI-3.0 is to optimize resource usage, either by recycling the resources or by using smart algorithms to efficiently handle requests from the various addons.
Exactly. Now someone comes along behind you can copy/pastes your stuff into their addon - if those things were in their own files, they could just copy the file as a whole and drop that in. So could you for that matter
Rather than suggest a design this time though, I'd like to just start a discussion on the merits of this concept.
I'm thinking of single addon libraries, and cut-and-paste code snippets. They both can be covered by the notion of a "static library". I have to use this term since the libraries we use today are "dynamic" in the sense that they interact with other copies of themselves (upgrading).
What I am thinking of is more like how Lua itself uses "libraries" in the form of modules - you get your own copy of the code, and it doesn't change at runtime.
One of my thoughts was to just use LuaCompat to enable the Lua module system for wow using an addon. Well - the flaw in that is that you'd need to get people to install an addon to enable the internal library in your addon - or make the addon a library which goes against the grain of what I want to achieve.
LibStub may work for single use libraries, but someone might reuse your single use library without you ever knowing (it is open source after all). Plus you don't need libstub if you aren't sharing a library.
We have access to a unique table for the addon a Lua file runs in. It seems we could use that table and come up with a scheme whereby we can just drop Lua files into our code and that would give us the advantages of code reuse without the stigma of being a shared library. It would also give other authors a way to write 'utility' code without creating 'yet another library'.
I could come up with a design but maybe some of you have some ideas?
https://github.com/tekkub/addontemplate
Yes this is almost exactly what I had in mind, i use something similar in Prat.
Static, Standalone, library code that is reusable but not shared in any way with other addons.
And the intended unit of reuse would be a single lua file - not really copy/paste.
Using LibStub doesn't really add any significant overhead, and if someone else uses your "private library", screw 'em. Unless the library is officially released, I think it's fairly clear to anyone with a brain that there's no support and no guarantee that future versions won't break compatibility. I use LibStub for "private" libraries, and a number of addons I use do the same, or roll their own shared libraries, and as far as I know nobody other than the original authors are using them. Plus, unless you specifically license the library for redistribution, you can easily stop someone from including it with addons, at least on the legitimate sites.
Furthermore, if your "private library" code is generalized enough that it's useful to more than one addon at a time, why not make it a shared library? Why have 5, 10, 50 copies of the same code loaded into memory at the same time?
Finally, what about updates? If there's a bug, then fixes aren't automatically shared with all addons using the code. Each author has to individually notice when there's an update, copy and paste the new file or code into his addon, and specifically release a new version of the addon. With shared libraries, authors don't need to deal with watching for updates, and it's not urgent to release a new version of every addon each time a library changes.
I don't use AceLocale-3.0 anymore, I often copy-paste like this:
Those pieces of code barely need to be turned into libraries. Moreover, they would gain nothing or little of being libraries. One of the strength of libraries like AceTimer-3.0 or AceGUI-3.0 is to optimize resource usage, either by recycling the resources or by using smart algorithms to efficiently handle requests from the various addons.
This sits somewhere between using a proper library to handle common/repeated tasks
(that in some cases would be overkill and has a steeper learning curve)
vs using "templates" to do that same common/repeated tasks when you don't need all the bells and whistles.
For one it might cut down on all the "help me get started with simple addons" threads..
"There look at those templates for proper event handling, saved variables etc"
I see nothing wrong with this if these templates are good.
I can second Phanx on that, this is mostly how I learned making my addons
Except however, that sometimes I didn't have any idea, what any specific piece of code actually did, because of lack of documentation, or sloppy coding (even though they were very simple). They weren't meant to be for learning addons I guess..
Then again, updating/improving the Welcome Home tutorial or [[Getting started with writing addons]] would also be a good resource for "help me get started" folks. But I'm getting offtopic~~
templates break over time and who wants to maintain non functioning code :P
also people should ask questions and join the community when they run into problems. i rather have them ask early and often rather than late with a big mess of code that nobody can read.
Using these code units is not just about "help me get started", it helps promote good program structure as well - so you just dont have 1 big blob. Also by separating out the boilerplate the main addon code is less cluttered, this physical separation helps prevent code for 1 thing getting intertwined with code from another thing.
And, as an aside. Copy/Paste doesn't help you learn anything either. Look how many addons have getglobal in them or this globals. Where do you think those came from in most cases.
Im thinking something like, a community maintained collection of 'templates' or whatever term is most appropriate which are added to through a meritocracy, ie. only those that are in use get added, and only those that are being used are part of the collection. Idk...just thinking.
Exactly. Now someone comes along behind you can copy/pastes your stuff into their addon - if those things were in their own files, they could just copy the file as a whole and drop that in. So could you for that matter