Create new instance of certain user type - lua

I'm using tolua++ to automatically expose C++ types to Lua. It seems that when I expose some type, e.g.
struct TestComponent
{
float foo;
string bar;
}
What tolua does (at least this is what it seems like to me) is add a new metatable to the lua environment (in this case it would just be called TestComponent) with some regular metamethods such as __add, __lt, as well as __index, __newindex, etc. It also has some custom functions (called .set and .get) which seem to be used when you get or set certain members of the struct/class. The type of TestComponent here seems to be just "table".
However, what it seems to lack, for simple structure definitions like above, are functions/methods to create a new instance of the type TestComponent, e.g.
a = TestComponent:new()
The question, then, is, how do I create a new instance of this type and assign it to a variable? For example, to hand it to a function that expects an argument of type TestComponent.

It's been a few years since I used tolua++, but based on the docs it appears that if your struct had a constructor, then you could create the object with a = TestComponent() or a = TestComponent:new() (both should work, unless you have an older version of tolua++). Without a constructor in the C++ struct, the docs don't say, but based on what you state, it seems like the TestComponent becomes a regular table object with the given fields and associated values, in which case it does not make sense to have a constructor (the table is the object, you can't create multiple instances of it).
So if you can edit the C++ header of the struct to add a constructor to it, it'll probably work. If you can't do that, then you could define a constructor yourself (note: not tested):
function TestComponent:new()
local obj = {}
for k,v in pairs(self) do
obj[k] = v
setmetatable(obj, self)
return obj
end
You might have to filter the keys so you only get values (not functions, for example), or replace the loop with explicit assignments such as:
function TestComponent:new()
local obj = {}
obj.foo = self.foo
obj.bar = self.bar
setmetatable(obj, self)
return obj
end

Related

Different methods of class instance initialization and how to find if the given object is an instance of particular class

I'm writing a module to generate some kind of encrypted access tokens. The encryption library I'm going to use (lua-resty-string.aes) uses the following method of class and class instance initialization:
local _M = { _VERSION = '0.14' }
local mt = { __index = _M }
function _M.new(...)
...
return setmetatable({ ... }, mt)
end
What is the fundamental difference of this initialization method with the following one (I'm more familiar with)?
Class = {}
Class.__index = Class
function Class.new()
return setmetatable({}, Class)
end
When I need to check is the variable passed to my function is an instance of the required class, for the second case I can use the following:
if getmetatable(obj) == Class then ...
However this is not working for the first case of initialization. I found the following works correctly:
local aes = require("resty.aes")
if (getmetatable(obj) or {}).__index == aes then ...
But I'm not sure is it OK or is there something more convenient to do it right? And what are the benefits of using the first method of class instance initialization?
Metatable-based classes
First of all, _M is just a naming convention for a module "namespace". You could name it "module" or "Class" as in your second example.The only real difference is the separation of metatable and "methodtable" / "class" table:
local Class = {}
local metatable = { __index = Class }
function Class.new(...)
...
return setmetatable({ ... }, metatable)
end
cleanly separates the two; the metatable is a local variable and thus kept "private" to the class (if the __metatable field is set, it can further be hidden from getmetatable). If the metatable should be exposed for convenient checks, one way to go would be a metatable field in the Class table:
Class.metatable = metatable
the other pattern just mushes the metatable and methodtable in the same table. Lua's metamethod naming using a double underscore as prefix (e.g. __index) is designed to allow this:
local Class = {}
Class.__index = Class
function Class.new(...)
...
return setmetatable({ ... }, metatable)
end
it requires a circular reference in the Class table (Class.__index); the metatable can be accessed from anywhere as long as the Class table is available because it is the metatable. Downsides of this include (1) potentially worse performance (due to hash collisions, because your metatable contains both the methods and the metamethods) and (2) somewhat dirty: If I inspected your Class table, it won't be neatly separated in metamethods and class methods; I'd have to separate it myself based on method naming.
It also means that indexing instances or the Class table allows "seeing" the underlying implementation which should probably be abstracted away / only accessible through indexing / using the operators / calling: Class.__index and instance.__index will be Class.
Instance checking
Now to the problem of checking whether an object is an instance of a Class: If the second approach is used, comparing the return value of getmetatable works:
if getmetatable(obj) == Class then
-- object is an instance of the class
end
if the metatable is exposed as Class.metatable or the like (may remind you of Object.prototype in JS), this works very similarly:
if getmetatable(obj) == Class.metatable then
-- object is an instance of the class
end
alternatively, the Class may implement it's own isinstance method that checks against the "private" (local) metatable:
function Class.isinstance(table)
return getmetatable(table) == metatable
end
a third alternative to allow the simply comparison against Class would be to set the __metatable field to Class:
local metatable = {__index = Class, __metatable = Class}
that way, the metatable is neatly localized and separated from the Class, yet from the outside it seems as if the "mushy" pattern was used.
If the metatable is however not exposed and no isinstance method is available, you may have to resort to hacks such as the one you have shown to implement this:
if getmetatable(obj).__index == Class then
-- object is an instance of the class
end
this doees however rely on __index being used in a specific way - a hidden implementation detail - and should, if possible, not be used in practice. Suppose __index is changed to an actual metamethod to log a warning because a field has been deprecated:
function metatable.__index(self, field)
if field == "deprecated_field" then warn"deprecated_field is deprecated, use field instead!"
return Class[field]
end
and suddenly your check breaks because the assumption that metatable.__index == Class simply doesn't hold anymore. An alternative hack to consider would be obtaining a metatable from an instance:
local instance = Class(...)
local class_metatable = getmetatable(instance)
...
if getmetatable(obj) == class_metatable then
-- object is probably an instance of the class
end

Get type of variable at run-time without having it assigned to an instance of an object and without mirrors

Is it possible to get the type of a variable in Dart at run-time, without having it assigned to an instance of an object and without using mirrors?
I know I can do this without mirrors (which is great!):
Foo foo;
foo = new Foo();
var fooType = foo.runTimeType; // This will give me a type of "Foo"
But I want to know the type of the variable before it is assigned to an object:
Foo foo;
var fooType = foo.runTimeType; // This will not give me a type of "Foo"
I am guessing it is not possible since the typing info is lost in run-time but would like to have it confirmed.
(My actual scenario is that I am doing dependency injection into a Polymer Element using Custom Events. I would like to put as much of this code as possible in an element base-class and have as little code as possible in each derived element class. One thing that I need to do this is to know the type of variables that are to be injected).

Using 'Object' functions in Lua?

I want to be able to have 'objects' with certain functions that refer to themselves (I have no idea what to call this) in Lua. I have seen code of what I'm trying to do but I have never understood what any of it actually means. I have tried looking over the Lua website but no luck.
Basic Code:
table = {}
function newTable(...)
...
return setmetatable(table)
end
function table:funcName(...)
...
end
Can someone explain what is going on here and how I can use this please? Thanks for reading!
missingno already mentioned one resource that explains how this works. You can also check out lua wiki's OOP section for more explanation and examples.
To summary briefly your example, starting with how to use it. Note, I changed some of the names so it doesn't affect the standard modules that comes with lua. You create a new object by calling newObject. You can invoke that object's methods using : followed by the method name:
-- create two instances
object1 = newObject()
object2 = newObject()
-- call 'my_function' method for object1
object1:my_function()
You'll need to know a bit about metatables to understand how this machinery works behind the scenes. When you perform a call like:
object1:my_function()
That is just syntax sugar for:
object1.my_function(object1)
This can be broken down further into:
object1["my_function"](object1)
Now object1 is just an empty table returned by newObject -- it doesn't have a "my_function" key. Normally this would result in an error because you're trying to call a nil value. However, you can change this behavior using metatables. The basic idea is to setup the __index metamethod to point to a table that holds your class methods:
object_table = {}
object_table.__index = object_table
function newObject(...)
return setmetatable({}, object_table)
end
The method lookup process will then look like this: object1 -> table. If object1 doesn't have a key, table is consulted next. If table has that key the associated value is returned. If table doesn't have it either then nil is returned since table doesn't have a metatable.
With this setup you can "override" a method for a particular object instance by just assigning the method name and function as key-value pair for that object.
object2.my_function = function (...)
-- do something different
end

Use of metatables in Lua

I'm trying to implement a object notation in Lua scripts.
Here is what I succeeded to do with the C API:
I created a new global table "Test" as a class and added a field "new" in it, pointing to a function written in C
i.e I can do this in lua code: "local obj = Test.new()" (it calls the function "new")
The "new" C function creates and returns a new table, and registers functions in it as fields (e.g "add", "count"...)
i.e I can do this: "obj:add("mike")" and "obj:count()" (obj is passed as first arguments with the ":" notation)
2 questions:
1) Everything works as expected, but the thing I'm wondering is: What is the advantage of using metatables in my case?
I see everywhere that metatables can help me to achieve what I tried to do, but I don't understand where they would be useful?
Adding fields to tables as methods isn't correct?
How could metatables help me (If added as my tables metatables)?
2) In fact I'm trying to reproduce the behaviour of C++ in Lua here.
For example, when I write this in C++: "Test *obj = new Test();"
I expect C++ and the constructor of Test to return me a pointer of an instance of Test.
This is exactly what I'm trying Lua to do for me.
The thing is that I use a table in this case, as the return of "new", but not a pointer so I can call methods on it later with Lua (using its fields), like a standard C++ object (with the operator ->).
To be able to retreive the actual pointer of my class in the C fonctions, I added a field "ptr" (light uservalue) to the table returned by "new". Without it, I would have been able to manipulate only the Lua table in my C function, nothing more (so no more method calls on the real pointer).
My second question is, Is it the right way to do it?
Do you have better idea on how to be able to manipulate my pointer everywhere without this "ptr" field?
Thank you,
Nicolas.
The main reason is that you get the __index metamethod.
Without it, every instance of a object has to have all the functions associated with it: which can make tables why large; and use a lot of memory.
local methods = {
foo = function() return "foo" end ;
bar = function() return "bar" end ;
bob = function() return "bob" end ;
hen = function() return "hen" end ;
}
So you have either
function new_no_mt ( )
local t = {}
for k , v in pairs ( methods ) do t [ k ] = v end
return t
end
vs
local mt = { __index = methods ; }
function new_mt ( )
return setmetatable ( { } , mt )
end
There are other benefits too;
defining operators;
easy type comparison via comparing metatables.
Changing method in metatable changes it for all objects, but changing it on one object only changes it for that object.
Otherwise, what you are trying to do sounds like the perfect situation for userdata.
userdata can only be indexed when you have an __index metatmethod (theres no table to put methods in)
What is the advantage of using metatables in my case?
Here's one.
Test.new = function() end
I just destroyed your ability to create new Test objects globally. If you had protected Test with a metatable, I would have had to really work to be able to do that.
Here's another:
local myTest = Test()
You can't do that without a metatable (overload the __call metamethod). And it looks much more natural for Lua syntax than calling Test.new.
And another:
local testAdd = Test() + Test()
Operator overloading. You can't do that without metatables.
Also:
This is exactly what I'm trying Lua to do for me.
Here's a tip: don't.
Different languages are different for a reason. You should do things in Lua the Lua way, not the C++ way. I can understand wanting to provide certain C++ mechanisms (like overloading and so forth), but you shouldn't use new just because that's what C++ uses.
Also, there are plenty of libraries that do this work for you. SWIG and Luabind are two big ones.

Accessing let bound fields from static members

Is there any way to access let bound fields from a static member? The following gives the indicated error:
type Foo(x) =
let x = x
static member test() =
let foo = Foo(System.DateTime.Now.Month)
printfn "%A" foo.x //the field, constructor or member 'x' is not defined
()
Whereas private explicit fields do allow access from static members:
type Bar =
val private x:int
new(x) = { x=x }
static member test() =
let Bar = Bar(System.DateTime.Now.Month)
printfn "%A" Bar.x
()
The documentation http://msdn.microsoft.com/en-us/library/dd469494.aspx states that "Explicit fields are not intended for routine use," yet accessing private instance fields from static members is certainly a routine scenario. Moreover, I don't believe you can set explicit fields within a primary constructor, which means if even one private instance field needs to be accessed from a static member, all of your fields must be moved over to explicit fields and you can no longer use a primary constructor -- it's all or nothing.
As real world example where you would actually want to access a private instance field from a static member, consider a big integer implementation: a BigInteger class would be immutable, so the internal representation of the big integer would kept as a private instance field (let's call it data). Now, suppose you felt an Add(other) instance method was inappropriate for an immutable data structure and you only wanted to implement a static Add(lhs,rhs) method: in this case, you would need to be able to access lhs.data and rhs.data.
I don't think you can do that... in fact, you can't access let-bound values from other instances either:
type Foo() =
let x = 3
member this.Test(f:Foo) =
f.x // same error
In general, if you need to access such a value from outside of the instance it belongs to, you should probably either create a private property to get the value or use a private field instead.
UPDATE
This is covered by section 8.6.2 of the spec. In particular:
Instance “let” bindings are lexically scoped (and thus implicitly private) to the object being defined.
Perhaps someone from the F# team will weigh in with a definitive answer as to why the language behaves this way. However, I can think of a couple of potential reasons:
let-bound values may not even be present as fields (e.g. again from the spec, a let binding will be represented by a local to the constructor "if the value is not a syntactic function, is not mutable and is not used in any function or member")
This seems consistent with the behavior of let bindings elsewhere in the language. See the examples of a roughly equivalent class and record definitions which I've included further down (because I can't seem to properly format code blocks within an ordered list...)
This provides a finer-grained level of encapsulation than is possible in many other languages - bindings which are local to the object being defined. Often, other instances will not need access to these bindings, in which case it's nice not to expose them.
If you want something which is accessible by other instances of your class (or from within static methods), there's an easy way to do that - create a private field or property, which has the benefit of explicitly expressing your intention that the value be accessible from outside of the instance that you are in.
As mentioned earlier, here are a roughly equivalent class definition and method to create a record:
type MyClass(i:int) =
let j = i * i
member this.IsSameAs(other:MyClass) =
false // can't access other.j here
type myRecord = { isSameAs : myRecord -> bool }
let makeMyRecord(i:int) =
let j = i * i
{ isSameAs = (fun r -> false) } //obviously, no way to access r.j here
Since constructors in F# are conceptually similar to any other function which returns an instance of a type (e.g. they can be called without using new), calling MyClass 5 is conceptually similar to calling makeMyRecord 5. In the latter case, we clearly don't expect that there is any way to access the local let binding for j from another instance of the record. Therefore, it's consistent that in the former case we also don't have any access to the binding.
yet, accessing let bound fields from
static members is certainly a routine
scenario
What do you mean here? What is the corresponding C# scenario (with an example)?
Note that this is legal:
type Foo() =
let x = 4
member this.Blah = x + 1
member private this.X = x
static member Test(foo:Foo) =
foo.X
That is, you can expose the let-bound value as a private member, which a static can read/use.

Resources