|
Hi there,
I'm trying to overwrite a function with reflection like this: Reflect.setField(this, methodName, function() { field();
callbackFunc(); }); The problem is that the new function has lost the old function's parameters. How do I make sure that these are passed to the old function regardless?
Thanks. - Tom
-- haXe - an open source web programming language http://haxe.org |
|
Tom, I have the feeling that you can try looking at Reflect.makeVarArgs , but I never really used it, nor is it available to the cpp target.
2010/7/12 Tom <[hidden email]> Hi there, -- haXe - an open source web programming language http://haxe.org |
|
Hi,
makeVarArgs converts a function with an array of arguments to a function with each array element as an argument. That's not what I need unfortunately. - Tom
2010/7/12 Cauê Waneck <[hidden email]> Tom, I have the feeling that you can try looking at Reflect.makeVarArgs , but I never really used it, nor is it available to the cpp target. -- haXe - an open source web programming language http://haxe.org |
|
With makeVarArgs, you can make a dynamic function that will take exactly the parameters you had on the old field, so you can pass to it.
Maybe something like this: var oldFunc = Reflect.makeVarArgs(Reflect.field(this, methodName)); Reflect.setField(this, methodName, Reflect.makeVarArgs(function(args:Array<Dynamic> { oldFunc(args); callbackFunc(); })); 2010/7/12 Tom <[hidden email]> Hi, -- haXe - an open source web programming language http://haxe.org |
|
Hi,
I tested that and that's not what makeVarArgs seems to do. Your code will result in all passed parameters to be passed to the first parameter. - Tom
2010/7/12 Cauê Waneck <[hidden email]> With makeVarArgs, you can make a dynamic function that will take exactly the parameters you had on the old field, so you can pass to it. -- haXe - an open source web programming language http://haxe.org |
|
You could look at the memoize snippet:
http://haxe.org/doc/snip/memoize Or, you could look at a technique I called "function decoration": http://scwn.net/2009/10/09/function-decoration-in-haxe-glue/ -Justin On Mon, Jul 12, 2010 at 1:48 PM, Tom <[hidden email]> wrote: Hi, -- blog: http://www.scwn.net aim: iujjd twitter: jjdonald -- haXe - an open source web programming language http://haxe.org |
|
In reply to this post by tommedema
Basically, what I would need there is a function to convert a function's parameters to an array with each parameter. makeVarArgs does the opposite.
- Tom
2010/7/12 Tom <[hidden email]> Hi, -- haXe - an open source web programming language http://haxe.org |
|
In reply to this post by Justin Donaldson-2
I got it working I do believe:
public function aop_objBindAfter(methodName:String, callbackFunc:Dynamic):Void { var field:Dynamic = Reflect.field(this, methodName);
if (field != null) { var me:Feature = this; var newFunc:Dynamic = Reflect.makeVarArgs(function(args:Array<Dynamic>) {
Reflect.callMethod(me, field, args); Reflect.callMethod(me, callbackFunc, args);
}); Reflect.setField(this, methodName, newFunc); }
} If anyone has any comments on this, eg. for improved performance, please tell me. Thanks! - Tom 2010/7/12 Justin Donaldson <[hidden email]> You could look at the memoize snippet: -- haXe - an open source web programming language http://haxe.org |
|
Your approach only works for void functions, if your function returns
something you need to return the result:
public function aop_objBindAfter(methodName:String,
callbackFunc:Dynamic):Void {
var
field:Dynamic = Reflect.field(this, methodName);
if
(field != null) {
var
me:Feature = this;
var
newFunc:Dynamic =
Reflect.makeVarArgs(function(args:Array<Dynamic>) {
var
res = Reflect.callMethod(me, field, args);
Reflect.callMethod(me,
callbackFunc, args);
return res; });
Reflect.setField(this,
methodName, newFunc);
}
}
Am 12.07.2010 23:07, schrieb Tom:
-- haXe - an open source web programming language http://haxe.org |
|
Thanks.
One problem I noticed is that it does not work for static functions. Apparently, Reflect.field(this, methodName) returns nothing if methodName is a static (class) method. I tried adding dynamic to the function declaration but that didn't help.
Any way to solve this? - Tom
2010/7/12 Heinz Hölzer <[hidden email]>
-- haXe - an open source web programming language http://haxe.org |
|
You need the class of your object:
Reflect.field(Type.getClass(obj), "staticmethod"); Am 12.07.2010 23:23, schrieb Tom: Thanks. -- haXe - an open source web programming language http://haxe.org |
|
That makes sense. Thanks.
Hopefully my last issue: how would I override a constructor like this? - Tom
2010/7/12 Heinz Hölzer <[hidden email]>
-- haXe - an open source web programming language http://haxe.org |
|
I don't think that this is possible on all platforms.
for neko it works this way (but this will definitely not work for avm2): var oldFunc = Reflect.field(Test, "new"); Reflect.setField(Test, "new", Reflect.makeVarArgs(function(args : Array<Dynamic>) { trace("before"); var result = Reflect.callMethod(Test, oldFunc, args); trace("result: " + result); trace("after"); return result; } )); Am 12.07.2010 23:58, schrieb Tom: That makes sense. Thanks. -- haXe - an open source web programming language http://haxe.org |
|
Is it not possible to retrieve the constructor function of a class?
- Tom
2010/7/13 Heinz Hölzer <[hidden email]>
-- haXe - an open source web programming language http://haxe.org |
|
In reply to this post by tommedema
Hi Tom,
If you look at the Glue class, this is essentially what is going on. You can access the original arguments of a function, and even preserve the type if you need to. Or, you can just put them in an array. Say you have a (dynamic) static/member function foo() that looks like: foo(x,y,z) : Int; you can write a quick helper function: var f = function(x,y,z) { trace([x, y, z]); } // here's your parameters in an array. and then "glue" it to the foo function as follows: foo = Glue.join3(foo, f); foo(1,2,3) now will call the f function as a side effect with the same arguments. Through the f function, you can access the original arguments... trace them, etc. The main benefit here is that typing and arity are preserved. Writing the helper function f() ensures that you are typing the arguments correctly, letting you safely do more sophisticated things with them. Variations of the Glue class will let you interrupt or overload the original method process, if that's what you want to do. -Justin On Mon, Jul 12, 2010 at 1:54 PM, Tom <[hidden email]> wrote: Basically, what I would need there is a function to convert a function's parameters to an array with each parameter. makeVarArgs does the opposite. -- blog: http://www.scwn.net aim: iujjd twitter: jjdonald -- haXe - an open source web programming language http://haxe.org |
|
Hi Justin,
I got that far yes. The only issue I have now is overriding constructor functions. - Tom
2010/7/13 Justin Donaldson <[hidden email]> Hi Tom, -- haXe - an open source web programming language http://haxe.org |
|
In reply to this post by tommedema
It's possible in javascript through overriding/setting the prototype + constructor. Php would need to override __construct (I think), and neko the field "new". I'm not really sure what is possible with C++. It's impossible in flash afaik.
So, unfortunately your best bet is trying to implement this through target specific magic (hopefully you're not using flash). http://haxe.org/doc/advanced/magic?lang=en -Justin On Mon, Jul 12, 2010 at 4:05 PM, Tom <[hidden email]> wrote: Is it not possible to retrieve the constructor function of a class? -- blog: http://www.scwn.net aim: iujjd twitter: jjdonald -- haXe - an open source web programming language http://haxe.org |
|
I am using flash aswell as Javascript.
Anyway, I'll tell the programmer to add this functionality through initializers: public function new() { init(); }
private function init() { //actual constructor } Then you can bind to the init method. - Tom
2010/7/13 Justin Donaldson <[hidden email]> It's possible in javascript through overriding/setting the prototype + constructor. Php would need to override __construct (I think), and neko the field "new". I'm not really sure what is possible with C++. It's impossible in flash afaik. -- haXe - an open source web programming language http://haxe.org |
| Powered by Nabble | See how NAML generates this page |
