|
On 14/07/2011 18.42, Steve Litt wrote:
[...]Well, that was to highlight the fact that "closure" wasn't a "simple" function, but had "Columns" as an upvalue.
I ran your preceding code and it worked, so you obviously had it
right. All I needed to do was understand it.
I don't know metatables so at first I thought you did something
magical, especially since you used the word "closure()" as a function.
Yes, actually that was the intent.
First thing I did was change both instances of that function name to
make sure it wasn't a reserved word deal, but it worked with the other
name. Then I took a very close look at your closure(), and realized it
was just a subroutine to postpone the running (as opposed to
declaring) of the columns.newCol() calls until after everything had
been defined.
The only problem with this approach is the garbage it generates: every new "instance" of the "Class" has its own newCol method, i.e. the methods are not shared. If this is not a problem for you, then all is fine (it depends on how many instances you actually create: if they are many and long-lived, they may eat up too much memory; if they are short-lived, they will impact performance because for every instance that is garbage collected, there are as many closures as there are methods to be collected too ).
Turned out for some reason I couldn't get columns=Columns.new({}) to
work inside of the closure when I converted everything to my way of
making objects, but that was trivial to solve. Watch this:
===============================
#!/usr/bin/lua
function user_configuration(columns)
-- ==== BEGINNING of USER-CUSTOMIZABLE OPTIONS ====
-- THESE *MUST* BE IN SPREADSHEET COLUMN ORDER!!!
-- IF THE SPREADSHEET CHANGES, CHANGE THIS LIST
-- ===================================
columns.newCol("recvdate" , {quantfield=false, fcn=this})
columns.newCol("fname" , {quantfield=false, fcn=this})
columns.newCol("lname" , {quantfield=false, fcn=this})
-- ==== END of USER-CUSTOMIZABLE OPTIONS ====
return(columns)
end
local Columns = {} -- THE CLASS
function Columns.new(property_names_a)
self={}
--local vars to keep state
--functions to act as methods
function self.newCol(name, properties)
--set up all the stuff about this column
end
return self
end
But this could be premature optimization, anyway. :-)
[...]It's a pleasure, but ... it's not genius, just careful reading ;-)
Clean as a whistle -- I'm going to use this every time there's user
config too complex to put in a text file. This is pure genius. Thank
you!
You may be interested in the following:
http://www.lua.org/manual/5.1/manual.html#2.8
http://lua-users.org/wiki/ObjectOrientedProgramming
http://www.lua.org/pil/6.1.html
http://www.lua.org/pil/13.html
http://www.lua.org/pil/16.html
Note: the "pil" book referenced above was written for an earlier version of Lua (5.0), but most material is still relevant (but be careful and use the refman as a disambiguation tool! ;-).IMHO inheritance is overvalued. In my experience composition can solve many problems in a cleaner and more self-contained way. Of course YMMV.
I'm also, in the next few days, going to use your OOP techniques as a
starting point to study OOP with metatables, which I understand is the
only way to do inheritance.
Thanks so much!
StevET
Cheers.
--Lorenzo