lua-users home
lua-l archive

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


Well then you may define a swig.oo model (eventually minimalist, like
PIL one, or richer like similar to C++) and stick to it for swig
generation. Maybe it will then become kind of de facto standard for lua
users. But I don't see why one could not leave with multiple class
models when proper scoping is defined.

When I want a minimalist and flexible oo model I use this (derived from
PIL and some posts in list). Maybe it can be of interest for you to
build a swig model.

--module("myoomodel", package.seeall)

local function search(k, plist) -- only "virtual" inheritance, from PIL
  for p in pairs(plist) do
    local v = p[k]
    if v then return v end
  end
  return nil
end

local function inherits_or_extend(derived, parent)
  -- one may also cache here a member closure in derived class
  local m = getmetatable(derived)
  m.__superclasses[parent] = true
  for parentparent in pairs(getmetatable(parent).__superclasses) do
    m.__superclasses[parentparent] = true
  end
  return derived
end

local function check_class(obj, class)
  local obj_class = getmetatable(obj)
  return class == obj_class or
getmetatable(obj_class).__superclasses[class] ~= nil
end

local function constructor(c, o)   -- constructor
  o = o or {}
  setmetatable(o, c)
  o.is_a = check_class -- instance semantic for is_a 
  return o
end

function class(c)
  c = c or {}
  c.is_a    = inherits_or_extend -- class semantic for is_a 
  local m = { __superclasses = {}, __call = constructor }
  function m.__index(t, k) return search(k, m.__superclasses) end
  setmetatable(c, m)
  c.__index = c
  return c
end

Node = class{parent=nil, child=nil, sibling=nil}
function Node:new() -- note than new isn't reserved, only class and is_a
are
  if self.parent then  self.parent:add_child(self) end
  return self
end
function Node:add_child(child)
  if not self.child then
    self.child = child
  else
    self.child:add_sibling(child)
  end
end
function Node:add_sibling(sibling)
  if not self.sibling then
    self.sibling = sibling
  else
    self.sibling:add_sibling(sibling)
  end
end
function Node:dump(indent)
  io.write(indent, "-+\n")
  if self.child then
    local ind = indent.." |"
    self.child:dump(ind)
    local ch = self.child.sibling
    while ch do
       ch:dump(ind)
       ch = ch.sibling
    end
  end
end

Base = class{}

Decoration= class{label=""}:is_a(Base)

local leave_count = 1
Leave = class{}:is_a(Node):is_a(Decoration)
function Leave:new()
  Node.new(self)
  if not self.label or self.label == "" then
    self.label = "default" .. leave_count
    leave_count = leave_count + 1
  end
  return self
end
function Leave:dump(indent)
  io.write(indent, "__ ", self.label, "\n")
end

root = Node{}:new() 
  l1 = Leave{ parent = root }:new()
  l2 = Leave{ parent = root }:new()
  node1 = Node{ parent = root }:new()
    l3 = Leave{ parent = node1 }:new()
    l4 = Leave{ parent = node1 }:new()
  node2 = Node{ parent = root }:new()
    l5 = Leave{ parent = node2 }:new()
    l6 = Leave{ parent = node2 }:new()
    node3 = Node{ parent = node2 }:new()
      l7 = Leave{ parent = node3 }:new()
      l8 = Leave{ parent = node3 }:new()
root:dump("")
print("l7 is a Leave: ", l7:is_a(Leave))
print("l7 is a Base: ", l7:is_a(Base))
print("node1 is a Leave: ",   node1:is_a(Leave))


-----Original Message-----
From: lua-bounces@bazar2.conectiva.com.br
[mailto:lua-bounces@bazar2.conectiva.com.br] On Behalf Of Sam Roberts
Sent: Monday, November 20, 2006 9:02 PM
To: lua@bazar2.conectiva.com.br
Subject: Re: Announce - SWIG-1.3.30

On Sat, Nov 18, 2006 at 02:12:53AM -0800, Don Hopkins wrote:
> Since everybody wants to roll their own object system in Lua, it would

> cool to parameterize the SWIG Lua runtime templates so you can hook in

> glue for any object system you want. But for now I just hacked my own
in!

Warning: [OT]

<rant>
I'm not part of that everybody!

Thats one of the things I never liked about scheme, and don't like
about lua either. The "hey, OO is easy, do it yourself in just 3 lines
of code!". The advantage of having an OO model builtin to the language
is it makes it easy to read people's code (you don't have to figure out
their flavor of OO first, LuaSocket, for example), and it makes it easy
for tools like swig to emit OO code in the language. As you say, swig
can't know the target OO system.

Anyhow, I put up with it in lua because luas has so many strengths when
used to extend C applications. Some of those strengths (small and fast,
a completely self-contained interpreter context that I can make multiple
instances of, good support for native threads, etc.) probaby derive from
the fact that it doesn't have an OO model or much of a standard library.
Still, it is a lack that I classify as a necessity of the
implementation, not a feature of the language.
</rant>

> I've found an easy way to plug a non-object-oriented C library into an

> object oriented language is to write a thin C++ class around it, and 

Thats a good idea, and I'll definitely keep it in mind next time I try
and swig anything, thanks.

One downside is that it isn't necessarily faster for me to write a thin
C++ wrapper for a C library than it is to directly bind the C library
into the target language. Writing lua in C is pretty easy.

I guess where the approach would really shine, though, is when you
target multiple output languages.

I have a lib I'm binding into lua now, and I'll probably bind into ruby
later. I might try swigging it at some time, to see how the approach
compares to hand-writing the bindings.

Cheers,
Sam