Information hiding is a concept that can be very useful in programming, and often goes hand in hand with concepts like modularity and code reuse, but I've learned it can be a double edged sword when working with old code that wasn't really modular to begin with.
In the process of hiding most of the code from the global name space, I've created a new issue - code that used to be able to see stuff in the global namespace and use it now can't see it and use it.
Which can be a bit of a problem, especially as a lot of Blizzard's own stuff is sitting there in the global name space. Which a lot of the old code uses.
So I went from issues with name clashes to issues of not being able to see stuff at all.
At first, it wasn't much of a problem, since it would usually throw and error and I could fix it easily.
But, in the last week before Regeant Restocker was released, I encountered some bugs where the code didn't throw an error, but rather exhibited some strange behavior. Those were pretty tricky to fix, as I had to figure out which variables were already being set by Blizzard before it loaded my code.
The next big change for Reagent Restocker is likely to include some actual design work, where I sit down and actually plan out how I want stuff to work in the future.
Reagent Restocker is already somewhat MVC like: Waterfall (now Ace3) was a separate library for handling the GUI, and the database is held in a single, easy to access table. I plan on keeping it close to that arrangement, although I'm playing around with some ideas to change some of the internals a bit.
Well, it seems I've coded myself into a corner. My checkboxes don't work, and I don't really know how to make them work in the current framework.
On one hand, I've got some old options table code that creates custom getter and setter functions for the options table and passes the functions to the rest of the code, and on the other hand, I've got the Ace widget library with some callbacks and some API functions.
Which wouldn't normally be such a big deal - since I'm passing functions around, I can just override the functions Ace supplies with the ones from the options table, right?
Well, actually, wrong. Ace recycles widgets, and the function overrides end up creating buggy behavior when a widget is recycled. In addition, the Ace getter and setter functions did some things that still need to be done, so I'm sorta working with functions from different parts of the code fighting over a similar purpose.
So - what am I to do?
Well, perhaps a move towards more MVC-like code. Right now, I have the model (a table) sending the logic that should be in the controller (the functions) to the view (the Ace library). In addition, the Ace library gladly takes code in a completely unknown state and recycles it, pretending it's new code. Which, of course, can lead to unintended side effects.
Pretty much every principle I've learned in computer science has been broken into a million tiny pieces by now.
So - right now, it looks like I need to pull out of the options table idea altogether and rethink how the different parts of code communicate. Passing functions around as if they were variables is cool, but gets in the way when different parts of the code want to do the same thing in different ways. It's time for a clearer separation of concerns in my code.
EDIT: Or I could look at the slider controls and replicate the way they work, since they're already working.
Well, after all this, the move to the new libraries is finally finished! I've got all of the basic functionality I want.
Now I get to step back, take a breath - and evaluate where to go from here.
For 2.0, I've determined that I'm keeping the core of Reagent Restocker simple. It's not going to be modified much from what the original author had. I've added some support files to make things a bit easier, especially when dealing with Ace's idiosyncrasies, but the core itself is going to remain simple and easy to maintain. Bug fixes and new features are certainly coming, but they'll be implemented in a manner consistent with how Reagent Restocker has worked in the past.
In addition, WoW 3.3 has added a table that is local to the entire addon - that's going to go a long ways towards solving name conflicts, as I can simply use that table as an environment the addon can use. In fact, now that I think about it, my attempt to create my own object oriented library system may have been a bit overkill, as it didn't really solve anything.
The only thing I wish for now is a cleaner separation between Blizzard's stuff and everything else in the global namespace. But that's not as important, and doesn't really affect functionality. As long name conflicts can be avoided without a lot of work, I'm good
Well, got a major blow to my plans today.
I was planning on something akin to a packaging/class system similar to how a lot of object oriented languages work, but I discovered something about how Lua works in WoW that makes it very difficult to do: After each file is finished, it appears that WoW resets the environment to the default global environment. So I can't have environment switches outside of the current file.
Without the ability to use Lua's own environment system outside of the current file, any class/packaging system basically becomes too complex to perform well. Oh well, so much for that idea.
Well, at least I've learned why nobody else appears to have tried to create something similar. It's not something that can be done in a separate library.
But - information hiding is still possible, and the setfenv function still works inside a file. Or I can just type "local" all of the time.
The whole purpose is to avoid name clashes. Something that's been bugging me ever since I took over Reagent Restocker. A large number of bugs that I've encountered can be traced to one addon clobbering a global value that another addon uses. So it's very desirable to put as much as possible in a different environment, where I don't have to worry about name clashes.
For now, it looks like I'm just making stuff private, while I think about another way of doing it. I'll probably just settle on some simple environment switching that can be easily copied and pasted into new files.
There's good news, however: The switch to the new library is pretty much finished. It's functional enough to take it out of alpha and start beta testing. I just need to make a final decision on how to handle name clashes.
Well, it looks like I made a mistake - I used a feature in some backup software that adds a lot of extra data to the folder. Ended up more than doubling the size of the download. Well, that's been fixed, and I apologize for the larger download.
The extra data does not affect the addon itself or how much memory it takes in WoW. It only affects the download size. I've re-uploaded a smaller file without the extra data.