Lua check if a table is an 'instance' - class

Given a table, is there a way to check if it is an instance object of any class?
Assume all class definition looks like:
Class = {}
Class.__index = Class
function Class.new()
return setmetatable({}, Class) -- returns an instance
end

I use just getmetatable function
if getmetatable(thing) == Class then
But if you use some type of inheritence then you can try this one
local A = {} A.__index = A
function A:new() return setmetatable({}, A) end
function A:foo() print('foo') end
local B = setmetatable({}, A) B.__index = B
function B:new() return setmetatable({}, B) end
function B:boo() print("boo") end
local function is_instance(o, class)
while o do
o = getmetatable(o)
if class == o then return true end
end
return false
end
local a = A:new()
local b = B:new()
a:foo()
b:foo()
b:boo()
print(is_instance(a, A))
print(is_instance(a, B))
print(is_instance(b, B))
print(is_instance(b, A))

In theory you could read table's metatable with getmetatable(), and compare received table agains list of classes known to you.
But it means metatable shouldn't be protected (__metatable field is not set to something different, getmetatable() is not removed within sandbox, etc), and you should know all available classes.
If there some metatable set on a table, it doesn't mean that table is a part of class hierarchy, or class at all. It just might use metatables to solve its own tasks.

Related

Structuring Lua classes

I'm constructing a class in Lua that has a number of groups of related functions within it, but am unsure whether there's a better way to structure it. I currently have to develop for a Lua 5.1 environment but am hopeful that Lua 5.3 will be possible in the near future.
The class will be used in a number of different Lua programs, so I want something I can just drop in as a single chunk of code (the environment I'm programming for means that modules and require aren't and won't be an option).
Ideally I want a black box piece of code (except for the exposed public methods) and not to duplicate code in different classes (to improve maintainability).
What I have at present is (generalised):
function Fclass()
--here I declare a bunch of local functions that can be called by any of the public methods
local function A(parms)
end
--Public methods set 1
--here I declare a bunch of state variables shared by BSelector and GetB
local BSelector = function()
A(parmvalues)
--returns a bunch of iup controls with supporting (complicated) logic
end
local GetB = function()
--returns the values of the iup controls created in Bselector
end
--Public methods set 2
--here I declare a bunch of state variables shared by DSelector and GetD
local DSelector = function()
--returns a bunch of iup controls with supporting (complicated) logic
end
local GetD = function()
A(parmvalues)
--returns the value of the iup controls created in Dselector
end
return{BSelector =BSelector , GetB =GetB, DSelector =DSelector , GetD =GetD}
end
The "B" and "D" groups of methods are totally independent except they both use the local functions "A" etc. (which don't depend on external variables); their state variables ideally should be local to the group.
Is this a sensible structure? Or should I be splitting the "B" and "D" groups into two separate classes and either duplicating the local functions or dropping them in as a separate piece of code? I don't really want to expose the local functions outside the classe(es) because there will inevitably be naming conflicts... Most programs will use all the groups of methods, although there will be some that only use a single group.
Or is there a better way to do this?
I'm invoking them thus:
myB = Fclass()
myD = Fclass()
someresults = myB.Bselector()
otherresults = myD.Dselector()
Updated to add: I'm advised I may not be using the terminology properly and what I'm doing isn't classes. My approach is based on Programming in Lua and was selected because I wanted to keep the state variables for the class? object? private -- not accessible except via the public methods.
In your example, it seems you encapsulate the state of your instances through closures, not table values.
While this has the advantage of stronger encapsulation, as upvalues are invisible from the outside without using the debug library, it also comes with the disadvantage that Lua has to close each method for each instance, wasting some more memory (not a lot though).
Another benefit is that when instance variables are implemented as table fields, they need not be declared before the method, as table indexing is string-based, whereas when implemented as closures, the local varaible needs to be known before the function is defined (this also applies to other methods, which in either implementation work the same way as instance variables).
It's more common to store instance variables as table values inside the object, and passing the object as a first argument to the functions. There's even syntactic sugar for this.
There's lots of ways for doing classes in Lua, with many different tradeoffs (some are better at inheritance, while others perform better, etc.)
Since you don't seem to need any inheritance, you can go with a simple factory function, as you're pretty much doing already.
The way I personally like to build such factory functions is:
local object do
local class = {}
local meta = {__index=class} -- Object metatable
function class:print() -- A method of the class
print("Hello, I am an object and my x is " .. tostring(self.x))
end
function object(self) -- The factory function for the Class
self.x = self.x or 0
return setmetatable(self, meta)
end
end
local o = object {
x = 20
}
o:print()
o.x = 30
o:print()
This has the benefit that, for classes with many methods and many instances, the methods aren't copied into every instance, which saves some memory.
Alternatively, you can do something like this
local object do
local function object_print(self)
print("Hello, I am an object and my x is " .. tostring(self.x))
end
function object(self)
self.x = self.x or 0
self.print = object_print -- Store method directly in the object
return self
end
end
Again, this saves a reference to every method in every instance, wasting some memory. The benefit is that you can now think of classes as traits. When you write
person { name = "henry" }
You can think of it as creating a new person with the name Henry, but you can also think of it as creating an object with the name Henry and adding the person trait to it.
Because of this benefit of combining two concepts of OOP into one implementation and not having any pesky inheritance, it's my favourite way of building objects in Lua in most simple cases.
Update
The trait approach also lends itself to defining several classes/traits together:
local person, human do
-- Some generic method shared by both classes
local function object_get_name(self)
return self.name
end
-- Person uses this as a method, but human uses
-- it as a function through an upvalue. Both work,
-- but have different upsides and downsides.
-- A method of person
local function person_say_hi(self)
print(self:get_name() .. " says hi!")
-- Calling get_name as a method here
end
-- A method of human
local function human_describe(self)
print(object_get_name(self) .. ' is a human!')
-- Calling get_name as an upvalue
end
function person(self)
self.name = self.name or 'A person'
self.say_hi = person_say_hi
self.get_name = object_get_name
-- Needs to be a method because person_say_hi assumes it to be one
return self
end
function human(self)
self.name = self.name or 'A human'
self.describe = human_describe
return self
end
end
-- Create a new person
local henry = person{ name = "Henry" }
henry:say_hi()
-- Create a new human
local steve = human { name = "Steve" }
steve:describe()
-- Change the way henry gets his name
function henry:get_name()
return self.name:upper()
end
-- This only affects henry; all other "person" objects keep their old
henry:say_hi()
-- This only works because say_hi accesses the method
-- Add the person trait to steve
person(steve)
steve:describe() -- Steve is still a human
steve:say_hi() -- Steve is also a person now
Some years ago I built myself a superclass for basic OOP functionality in Lua.
Usage:
Person = LuaObject:extend({
__name = "Person",
name = "",
age = 0,
})
-- constructor
function Person:new(name, age)
Person.__super.new(self)-- calling the super constructor
self.name = name
self.age = age
end
function Person:getName()
return self.name
end
function Person:getAge()
return self.age
end
Feel free to use it:
--[[
LuaObject for basic OOP in Lua
Lua 5.0
]]
local function newIndexFunction(tbl, name, value)
if name == "new" and type(value) == "function" then
local constructor = value
rawset(tbl, name, function(self, ...)
local object = self
if object.__class == nil then
object = {}
object.__class = self
object.__id = string.sub(tostring(object), 8)
self.__index = self
setmetatable(object, self)
end
constructor(object, unpack(arg))-- Lua 5.0
-- constructor(object, ...)-- Lua 5.1+
return object
end)
else
rawset(tbl, name, value)
end
end
local function toStringFunction(tbl)
return tbl:toString()
end
LuaObject = {__name = "LuaObject"}
setmetatable(LuaObject, {__newindex = newIndexFunction, __tostring = toStringFunction})
function LuaObject:extend(class)
class = class or {}
self.__index = self
self.__newindex = newIndexFunction
self.__tostring = toStringFunction
local constructor = nil
if class.new ~= nil then
constructor = class.new
class.new = nil
end
setmetatable(class, self)
if constructor ~= nil then
class.new = constructor
end
class.__super = self
return class
end
function LuaObject:new()
end
function LuaObject:getSuperClass()
return self.__super
end
function LuaObject:getClass()
return self.__class
end
function LuaObject:toString()
return string.format("[%s] %s", self.__class.__name, self.__id)
end
function LuaObject:isInstance(value)
return value ~= nil and type(value) == "table" and getmetatable(value) == self
end
--[[
-- examples
-- basic class
Person = LuaObject:extend({
__name = "Person",
name = "",
age = 0,
})
-- constructor
function Person:new(name, age)
Person.__super.new(self)-- calling the super constructor
self.name = name
self.age = age
end
function Person:getName()
return self.name
end
function Person:getAge()
return self.age
end
-- extending classes
Customer = Person:extend({
__name = "Customer",
id = 0,
})
function Customer:new(id, name, age)
Customer.__super.new(self, name, age)
self.id = id
end
function Customer:getID()
return self.id
end
-- overriding methods
function Customer:getName()
-- calling super methods
local realResult = Customer.__super.getName(self)
if string.len(realResult) <= 5 then
return realResult
else
return string.sub(realResult, 1, 5)
end
end
-- testing
local customer1 = Customer:new(1, "rollback", 19)
local customer2 = Customer:new(2, "Kori", -1)
print(assert(customer1:getName() == "rollb", "Overriding of getName failed"))
print(assert(customer2:getName() == "Kori", "Overriding of getName failed"))
print(assert(customer1:getID() == 1, "Error in getID"))
print(assert(customer1:getAge() == 19, "Error in getAge"))
print(customer1)
]]
You can create 2 up-values for your class functions. the 1st value holds public variables that will be accessed by your class' caller, such as the functions themselves and any caller handled options.
while the 2nd will be for your private values those that are only known and accessible from within the class. You can use this private table to store internal state or other inner workings that will not be exposed to the caller.
function class(first, second)
local public = {first}
local _private = {second}
function _private.A(parms)
--private function not available outside of class.
end
function public:selector() -- public class available to caller
_private.A(parmvalues) -- calls private class
end
function public:get()
return _private[1]
end
return public
end
myB = class('hello', ' world!') --passing in a variable for public, and one for private.
myD = class('hello...', ' world?')
print(myB[1] .. myB:get()) --get a public value, and uses get function to retrieve private value
print(myD[1] .. myD:get())
Additionally if the class functions should never be changed by your user, you can enforce that by changing return public to:
local meta = {
__index = public,
__newindex = function(t, k, v)
error("this table is read-only")
end,
__metatable = false
}
return setmetatable({}, meta) -- this make the public table read only

Exclude derived entities from requests to the base class

I have this DbContext:
public class DataContext : DbContext
{
public DbSet<Base> Bases {get;set}
public DbSet<Sub> Subs {get;set}
}
Sub is a subclass of Base.
When I'm querying the list of Base entities like so:
Context.Bases.ToListAsync()
It returns me every entities, either Base or Sub.
How can I configure my model context to get only the entities that are of Base type and not the ones that derives from it.
The best (or least worst) solution I found is to directly use the shadow property:
Context.Bases.Where(b => EF.Property<string>(b, "Discriminator") == "Base")).ToListAsync();
It works but needs to be repeted now and then, each time I need to query Bases. I'd have prefered a solution in the OnModelCreating method.
I'll accept this answer unless someone else find a better solution.
You'd have to use OfType<T>:
var basesOnly = await _context.Bases.OfType<Base>().ToListAsync();
UPDATE
Sorry, then. I could have sworn the above works, but it doesn't. The next best method I can think of is to simply filter out the types you don't want. It's not ideal, because it requires specifying all subtypes in your query, which then means you need to remember to update it if you add more subtypes.
var basesOnly = await _context.Bases.Where(x => !(x is Sub)).ToListAsync();
How can I configure my model context to get only the entities that are
of Base type and not the ones that derives from it.
You cannot. Every Sub is a Base. So querying all Bases includes all Subs. Eg code like the following must succeed:
Base b = db.Bases.Where(i => i.Id == 1).Single();
if (b is Sub)
begin
Sub s = (Sub)b;
. . .
end
else //other Sub
begin
Sub2 s = (Sub2)b;
. . .
end
You can fetch an anonymous type with the just the base class properties.
And asking this question suggests that inheritance might is not the right modeling technique for your scenario.
If what you want it to fetch the Entities of type Base, but not the subtype Sub, then you can do that with a query like:
var q = from b in db.Bases
where !(b is Sub)
select b;
Which translates to :
SELECT [b].[Id], [b].[Discriminator], [b].[Name], [b].[Size]
FROM [Bases] AS [b]
WHERE [b].[Discriminator] IN (N'Sub', N'Base')
AND NOT ([b].[Discriminator] = N'Sub')
But you can't (currently) exclude all subtypes without enumerating them. Eg this query:
var q2 = from b in db.Bases
where b.GetType() == typeof(Base)
select b;
Will not be completely translated to SQL, and will filter out the subtypes on the client.

classes with inheritance the simplified way?

EDIT I have found a much easier way to do this in lua but the problem is method inheritance
basically the syntax would go like this
Object
object = {}
object.base = ?
object.value = 0
function object:create(x, y)
local copy
--copy table
if type(self) == "table" then
copy = {} for k, v in pairs(self) do copy[k] = v:create() end
else
copy = self
end
--set base
copy.base = self
--set copy vars
copy.x = x
copy.y = y
return copy
end
function object:update()
self.value = self.value + 1
end
Player
player = object:create()
player.value = 1
function player:create(x, y, size)
base:create(x, y) --inherit base event
end
--automaticly inherits update event since it is not redeclared
I'm not sure how to go about doing this though
Inheritance in Lua is basically implemented using metatables. In code:
function object:new (o)
o = o or {}
-- Put the rest of your create function code here
setmetatable(o, self)
self.__index = self
return o
end
function object:update()
self.value = self.value + 1
end
Now create an empty Player class that will be a subclass of your base Object class and will inherit all its behavior from it.
Player = Object:new()
Player is now an instance of Object. Instantiate a new Player object, p in order to inherit the new method from Object.
p = Player:new{x=1, y=2, size=3}
This time, however, when new executes, the self parameter will refer to player. Therefore, the metatable of p will be Player, whose value at index __index is also Player. So, p inherits from Player, which inherits from Object.
Now when you'll code:
p:create{x=10, y=20, size=100}
lua won't find a create field in p, so it will look into Player class; it won't find a create field there, too, so it will look into Object and there it will finds the original implementation of create. The same thing will happen with the update function.
Of course Player class can redefine any method inherited from its superclass, Object. So for example you can redefine -if you want- the create function:
function Player:create()
--New create code for Player
end
Now when you'll call p:create{x=10, y=20, size=190}, Lua will not access the Object class, because it finds the new create function in Player first.
You are making a reference to base directly, whereas, it is actually an attribute of your player object:
function player:create(x, y, size)
self.base:create(x, y)
end

Avoid repeating a superclass' package name in Matlab

How can I avoid repeating a long tedious package name in matlab classes in the following cases:
When specifying the Superclass, e.g. classdef Class < tediouspkgname.Superclass
When calling the superclass constructor, e.g. obj = obj#tediouspkgname.Superclass(...).
When calling superclass methods, e.g. val = somefunc#tediouspkgname.Superclas(...).
I'm looking for an equivalent of matlabs import statement, which is not usable in these cases unfortunately.
MWE:
Lets have a folder called +tediouspkgname/ in our Matlab path. So Matlab recognizes there's a package called tediouspkgname.
Lets have a Class ExampleClass which is saved in the file +tediouspkgname/ExampleClass.m:
classdef ExampleClass
properties
p
end
methods
function obj = ExampleClass(p)
obj.p = p;
end
function print(obj)
fprintf('p=%s\n',obj.p);
end
end
end
Let there be another Class, derived from ExampleClass, living in the file
+tediouspkgname/DerivedClass.m:
classdef DerivedClass < tediouspkgname.ExampleClass
methods
function obj = DerivedClass(p)
obj = obj#tediouspkgname.ExampleClass(p);
end
function print(obj)
print#tediouspkgname.ExampleClass(obj);
fprintf('--Derived.\n');
end
end
end
I want the following commands to work without errors while mentioning tediouspkgname. as little as possible:
e = tediouspkgname.ExampleClass('Hello');
e.print();
o = tediouspkgname.DerivedClass('World');
o.print();
In particular, this definition of DerivedClass gives me the error ExampleClass is not a valid base class:
classdef DerivedClass < tediouspkgname.ExampleClass
methods
function obj = DerivedClass(p)
obj = obj#tediouspkgname.ExampleClass(p);
end
function print(obj)
import tediouspkgname.ExampleClass
print#ExampleClass(obj);
fprintf('--Derived.\n');
end
end
end
You have two examples at the command line:
e = tediouspkgname.ExampleClass('Hello');
e.print();
o = tediouspkgname.DerivedClass('World');
o.print();
For these cases, you can use import at the command line:
import tediouspkgname.*
e = ExampleClass('Hello');
e.print();
o = DerivedClass('World');
o.print();
and it should work fine.
For the other cases you have (in the class definition line, and when calling a superclass method), you need to use the fully qualified name including the package.
I dislike this aspect of the MATLAB OO system. It's not just that it's tedious to write out the fully qualified name; it means that if you change the name of your package, or move a class from one package to another, you have to manually go through your whole codebase in order to find-and-replace one package name for another.

How to add event listener for an object that i assigned a value from another class in Lua?

I am trying to write a touch event for the object that i assigned the value of another class' function value into. However, it gives me this error: attempt to call 'addEventListener' nil value.
Here is my fish.lua code:
function class()
local cls = {}
cls.__index = cls
return setmetatable(cls, {__call = function (c, ...)
instance = setmetatable({}, cls)
if cls.__init then
cls.__init(instance, ...)
end
return instance
end})
end
Color= class()
function Color:__init(image)
self.image=display.newImage(image,30,30)
end
originalImage="fish.small.red.png"
differentImage="fish.small.blue.png"
And here is my main.lua code:
require "fish"
local fishImage=Color(originalImage)
function listen(event)
if(phase.event=="began") then
fishImage=Color(differentImage)
end
end
fishImage: addEventListener("touch", listen)
fishImage is an instance of a class you created (Color) which doesn't have a method named addEventListener, at least not in the code you've shown. Perhaps you meant:
fishImage.image:addEventListener('touch', listen)
Which is adding an event listener to the corona image object your Color class encapsulates.
You have a lots of bugs. But use this as an example:
fish.lua
local fish = {}
fish.color = function(image)
local image = display.newImage(image,30,30)
return image
end
return fish
main.lua
display.setStatusBar(display.HiddenStatusBar)
local fish = require("fish")
local fishImage = fish.color("Icon.png")
local function listen(event)
if(event.phase=="began") then
fishImage=fish.color("Icon-60.png")
end
end
fishImage:addEventListener("touch", listen)