lua / luabind - Add and overwrite class methods through lua - indexing

I'm using lua 5.2.2 with luabind 0.9.
I'd like to be able to add additional class-methods through lua for any classes that I've bound in c++, but I'm unsure how to do it.
The problem is that luabind uses a function as the __index-metamethod for any bound classes instead of a table, so I don't see a way to access the class-methods at all.
e.g., I'm binding my classes like this:
luabind::module(lua)
[
luabind::class_<testClass>("TestClass")
.def(luabind::constructor<>())
.def("TestFunc",&TestFunc)
];
What I essentially want to do is to add a lua-function to the list of methods for this class, and be able to overwrite existing ones:
local t = tableOfClassMethods
local r = t.TestFunc -- Reference to the c++-function we've bound
t.SomeFunction = function(o) end -- New function for all objects of this class
t.TestFunc = function(o) end -- Should overwrite the c++-function of the same name
Any help would be appreciated.

You could use a luabind::object property and register it with the .property method of luabind
Something like this:
//Class
class FunctionCaller
{
public:
luabind::object Fn;
void SetFn(luabind::object NewFn)
{
Fn = NewFn;
};
luabind::object GetFn()
{
return Fn;
};
};
//Binding Code
luabind::class_<FunctionCaller>("FunctionCaller")
.def(luabind::constructor<>())
.property("Fn", &FunctionCaller::Fn, &FunctionCaller::SetFn, &FunctionCaller::GetFn)
Then you just need to call the luabind::object according to the luabind docs.
It's not exactly what you want to do but it could help you overwrite the function I think. You could bind the real function and have a property, check if the luabind::object is non-null, and call it or the native function.

Related

Testing private methods in Raku

Is there a way to test private methods in Raku?
I understand that one should ideally define their tests targeting the public methods, but is there a way to do it "the wrong way"? :)
I initially thought about defining a subclass for the Testing that inherited from the class I wanted to test and do the tests there, but it seems that private methods are not inherited.
Then I saw the 'trusts' routine, but I wouldn't want to reference a Testing class on any of the classes of the code.
Is there something like changing the 'private' property of a method via introspection?
What would be the best way to call/test a private method?
This can be done using introspection.
Consider this is the class you want to test:
class SomeClass {
has Int $!attribute;
method set-value(Int $value) returns Nil {
$!attribute = $value;
return;
}
method get-value returns Int {
return $!attribute;
}
# Private method
method !increase-value-by(Int $extra) returns Nil {
$!attribute += $extra;
return;
}
}
You may create a test like this:
use Test;
use SomeClass;
plan 3;
my SomeClass $some-class = SomeClass.new;
my Method:D $increase-value = $some-class.^find_private_method: 'increase-value-by';
$some-class.set-value: 1;
$increase-value($some-class, 4);
is $some-class.get-value, 5, '1+4 = 5';
$increase-value($some-class, 5);
is $some-class.get-value, 10, '5+5 = 10';
my SomeClass $a-new-class = SomeClass.new;
$a-new-class.set-value: 0;
$increase-value($a-new-class, -1);
is $a-new-class.get-value, -1, '0+(-1) = -1; The method can be used on a new class';
done-testing;
You first create an instance of the class and the use ^find_private_method to get its private Method. Then you can call that Method by passing an instance of a class as the first parameter.
There's a more complete explanation on this answer:
How do you access private methods or attributes from outside the type they belong to?
A fresh cup of tea and #Julio's and #JJ's answers inspired the following:
class SomeClass { method !private ($foo) { say $foo } }
use MONKEY-TYPING; augment class SomeClass { trusts GLOBAL }
my SomeClass $some-class = SomeClass.new;
$some-class!SomeClass::private(42); # 42
My solution tweaks the class using monkey typing. Monkey typing is a generally dodgy thing to do (hence the LOUD pragma). But it seems tailor made for a case just like this. Augment the class with a trusts GLOBAL and Bob's your Uncle.
Raku requires the SomeClass:: qualification for this to work. (Perhaps when RakuAST macros arrive there'll be a tidy way to get around that.) My inclination is to think that having to write a class qualification is OK, and the above solution is much better than the following, but YMMV...
Perhaps, instead:
use MONKEY-TYPING;
augment class SomeClass {
multi method FALLBACK ($name where .starts-with('!!!'), |args) {
.(self, |args) with $?CLASS.^find_private_method: $name.substr: 3
}
}
and then:
$some-class.'!!!private'(42); # 42
I've used:
A multi for the FALLBACK, and have required that the method name string starts with !!!;
A regular method call (. not !);
Calling the method by a string version of its name.
The multi and !!! is in case the class being tested already has one or more FALLBACK methods declared.
A convention of prepending !!! seems more or less guaranteed to ensure that the testing code will never interfere with how the class is supposed to work. (In particular, if there were some call to a private method that didn't exist, and there was existing FALLBACK handling, it would handle that case without this monkey FALLBACK getting involved.)
It should also alert anyone reading the test code that something odd is going on, in the incredibly unlikely case that something weird did start happening, either because I'm missing something that I just can't see, or because some FALLBACK code within a class just so happened to use the same convention.
Besides using introspection, you can try and use a external helper role to access all private methods and call them directly. For instance:
role Privateer {
method test-private-method ( $method-name, |c ) {
self!"$method-name"(|c);
}
}
class Privateed does Privateer {
method !private() { return "⌣" }
}
my $obj = Privateed.new;
say $obj.test-private-method( "private" );
The key here is to call a method by name, which you can do with public and private methods, although for private methods you need to use their special syntax self!.

Chain up to 'Gtk.Box.new' not supported

I'm new to Vala and so far I think it's pretty cool but I'm having trouble understanding inheritance. I read here that I should use base() to call the parents constructor. Alright, cool, seems understandable but It din't work for me. I kept getting the error on the title. Here is my snippet to show:
public class MyBox : Gtk.Box {
public MyBox(Gtk.Orientation orientation, int spacing) {
// I have to this
this.set_orientation(orientation);
this.set_spacing(spacing);
// I want to do this:
base(orientation, spacing);
//workaround is this:
Object(orientation: orientation, spacing: spacing);
}
}
Please help me understand why Object(....) works but not base(...)
Shouldn't it be the same thing?
This is due to implementation of the C code. When Vala generates a constructor, it generates two C functions a _new function that allocates memory and calls the _construct and a _construct function that initialises the object. When you case the base constructor using base(), it needs a matching _construct function to call. Not all the classes written in C have this; in the VAPI file, you will find has_construct_function = false for some constructors. If this is the case, no chain-up can be done. The base GObject can set properties from arguments, so this becomes the only way to set defaults in the base class.

What is the syntax to declare a unique_Ptr variable in a header, then assign it later in the constructor?

I have coded the following, and am very new to c++, and it feels clumsy. I am trying to give 'spriteBatch' (a unique_Ptr) class scope. Here's the header file:
ref class CubeRenderer : public Direct3DBase
{
public:
CubeRenderer();
~CubeRenderer();
private:
std::unique_ptr<SpriteBatch> spriteBatch;
};
Then in the cpp file Constructor, this:
std::unique_ptr<SpriteBatch> sb(new SpriteBatch(m_d3dContext.Get()));
spriteBatch = std::move(sb);
It just seems clumsy the way I had to create 'sb' and move it to 'spriteBatch'. attempting to assign directly to 'spriteBatch' failed (maybe I simply don't know the proper syntax). Is there a way to avoid needing to use 'sb' & std::move?
Thank you.
The following should work fine:
spriteBatch = std::unique_ptr<SpriteBatch>(new SpriteBatch(m_d3dContext.Get()));
Alternatively, you can avoid repeating the type name with some make_unique function.
spriteBatch = make_unique<SpriteBatch>(m_d3dContext.Get());
There's also the reset member:
spriteBatch.reset(new SpriteBatch(m_d3dContext.Get()));
But, since you mention a constructor, why not just use the member initialization list?
CubeRenderer::CubeRenderer()
: spriteBatch(new SpriteBatch(m_d3dContext.Get())) {}

c++/cli reference to property

Well, I haven't yet found something that says this is impossible, though I'm starting to think it might be. Can you make this work?
using namespace System;
template <typename T>
void unset(Nullable<T>& var) { var = Nullable<T>(); }
void unset(String^% var) { var=nullptr; }
//this is really a C# class in my situation, so I can't change its types
public ref class Foo
{
public:
property Nullable<Decimal> Dec;
property Nullable<int> Num;
property String^ Str;
};
int main()
{
Foo^ foo = gcnew Foo;
foo->Dec = Decimal(1.2);
foo->Num = 3;
foo->Str = "hi";
unset(foo->Dec);
unset(foo->Num);
unset(foo->Str);
Console::WriteLine(foo->Dec);
Console::WriteLine(foo->Num);
Console::WriteLine(foo->Str);
}
Update: unset is called from a code-generating macro which is called on about 50 params. I'd prefer not to have to go make varieties of the macro for each type.
It isn't possible. Setting a property requires calling the property setter function. There is no way to guess for the called method that it needs to call a function vs can assign the passed variable pointer. If you really want to do this then pass a delegate.
There is actually one .NET language that supports it, VB.NET generates code like this:
T temp = obj->prop;
func(temp)
obj->prop = temp;
There is however a dreadful aliasing problem with that, quite undebuggable. This goes belly up in the (rare) case where func() also uses the property. This is otherwise the way you'd work around the limitation, explicitly in your own code.
Beware that your code is wrong, possibly intentional, you are passing a C++ & reference, not a managed % interior pointer. The compiler is going to bitch about that, you can't create references or pointers to managed objects. They move. Unless the reference is to a variable on the stack. It doesn't otherwise change the answer.
For those who may end up here wondering how I got on with this, I ended up being lucky that the class I was working with was an LLBLGen Entity, so I was able to replace
unset(re->var);
with
{ SD::LLBLGen::Pro::ORMSupportClasses::IEntityField2^ f = re->Fields[#var]; \
if (f->IsNullable) \
f->CurrentValue = nullptr; }

Using dojo.require() without dojo.declare()

I'm quite confused from Dojo's documentation. How can I use dojo.require() without actually using dojo.declare()? The reason I don't want to use dojo.declare() is that it exposes declared class as global variable.
Right now my code looks like this:
HTML file:
dojo.require('module.test');
Module/test.js:
dojo.provide('module.test');
function test() {
return 'found me';
}
I just can't get Dojo to return test() method anywhere. What's the correct pattern for using dojo.require() without declaring?
I think you are confusing dojo.provide/dojo.require with dojo.declare. They are completely different concepts.
Things that relate to modules
dojo.provide defines a module.
dojo.require requires that a module be defined before running any code later.
Things that relate to JavaScript classes
dojo.declare is something completely different. It declares a Dojo-style class.
You can have multiple classes in a module, or several modules making up one class. In general, modules !== classes and they are completely unrelated concepts.
dojo.provide defines the code module so that the loader will see it and creates an object from the global namespace by that name. From that point, you can anchor code directly to that global variable, e.g.
Module/test.js:
dojo.provide('module.test');
module.test.myFunc = function() {
return 'found me';
}
There are various patterns you can use, such as creating a closure and hiding "private" function implementations, exposing them via the global reference you created in dojo.provide:
dojo.provide('module.test');
function(){
// closure to keep top-level definitions out of the global scope
var myString = 'found me';
function privateHelper() {
return myString;
}
module.test.myFunc = function() {
return privateHelper();
}
}();
Note that the above simply puts methods directly on an object. Now, there's also dojo.declare, which is often used with dojo.provide to create an object with prototypes and mixins so that you can create instances with the 'new' keyword with some inheritance, even simulating multiple inheritance vai mixins. This sort of OO abstraction is often overused. It does approximate the patterns required by languages like Java, so some folks are used to declaring objects for everything.
Note that as of Dojo 1.5, dojo.declare returns an object and does not necessarily need to declare anything in the global scope.
Here's a pattern I sometimes use (this would be the contents of test.js):
(function() {
var thisModule = dojo.provide("module.test");
dojo.mixin(thisModule, {
test: function() {
return "found me";
}
});
})();
Now you can reference module.test.test() in your HTML page.