lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 14/07/2011 18.42, Steve Litt wrote:
[...]

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.

Well, that was to highlight the fact that "closure" wasn't a "simple" function, but had "Columns" as an upvalue.

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.

Yes, actually that was the intent.


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

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 ).

But this could be premature optimization, anyway. :-)

[...]

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!

It's a pleasure, but ... it's not genius, just careful reading ;-)
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! ;-).


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.

IMHO inheritance is overvalued. In my experience composition can solve many problems in a cleaner and more self-contained way. Of course YMMV.


Thanks so much!

StevET

Cheers.
--Lorenzo