[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: host-plugin interface
- From: steve donovan <steve.j.donovan@...>
- Date: Tue, 9 Feb 2010 14:04:21 +0200
On Tue, Feb 9, 2010 at 1:05 PM, Thijs Koerselman
<thijskoerselman@gmail.com> wrote:
> Thanks for the example, but I don't understand how it relates to my original
> question. I would like to define the plugin interface similar to a C++
> abstract base class.
Here's one solution to Lua abstract classes:
-- define a Base class
Base = {_abstract = {}}
Base.__index = Base
-- these 'methods' are abstract and any derived class must implement them
Base._abstract.one = true
Base._abstract.two = true
-- not abstract, will be inherited directly
function Base:three ()
end
function Base.check (object)
-- is it derived from us?
if not object._base == Base then
return nil,"object is not derived from Base"
end
local mt = getmetatable(object)
if not mt then
return nil, "object does not have a metatable"
end
-- does it implement the required abstract methods?
local abstract_members = Base._abstract
for abstract in pairs(abstract_members) do
if not mt[abstract] then
return nil,"object does not implement "..abstract
end
end
-- copy all non-abstract functions from Base into the derived class
-- (being careful not to overwrite any overrides)
for member,value in pairs(Base) do
if not mt[member] then
mt[member] = value
end
end
return object
end
Derived = {_base = Base}
Derived.__index = Derived
function Derived.new ()
return setmetatable({},Derived)
end
function Derived:one ()
end
function Derived:two () end
obj = Derived.new()
print(Base.check(obj))
Now, if you were to comment out the Derived:two function, then you
will see an appropriate error message.
A plugin file would probably look like this
-- plugin.lua -------------
require 'base'
module ('plugin',package.seeall) -- for convenience
Derived = {_base = Base}
Derived.__index = Derived
function Derived:one () ... end
function Derived:two () ... end
return setmetatable({},Derived)
-----------------------------
Then you can do
obj,err = Base.check(require ('plugin'))
Obviously we can wrap this pattern so that some repeated code is factored out.
steve d.