Ticket #2460
Just to mention that currently there's no bind() or retype() methods for Func in Javascript.
bind()
retype()
Func
bind() I can often get away with by creating a new closure that call the original func with the new arguments. But I don't know a way around retype().
Ticket promoted to #2460 and assigned to andy
An accumulated patch for Func.retype(), adding methods to Func.js and MethodFunc.js:
Func.retype()
Func.js
MethodFunc.js
diff -r 56d95b6fa8ad src/sys/js/fan/Func.js --- a/src/sys/js/fan/Func.js Tue Sep 22 09:31:42 2015 -0400 +++ b/src/sys/js/fan/Func.js Wed Sep 23 01:39:57 2015 +0100 @@ -76,6 +76,22 @@ fan.sys.Func.prototype.exitCtor = function() {} fan.sys.Func.prototype.checkInCtor = function(obj) {} +fan.sys.Func.prototype.toStr = function() { return "sys::Func"; } + +fan.sys.Func.prototype.retype = function(t) +{ + if (t instanceof fan.sys.FuncType) + { + var params = []; + for (var i=0; i < t.pars.length; ++i) + params.push(new fan.sys.Param(String.fromCharCode(i+65), t.pars[i], 0)); + var paramList = fan.sys.List.make(fan.sys.Param.$type, params); + return fan.sys.Func.make(paramList, t.ret, this.m_func); + } + else + throw fan.sys.ArgErr.make(fan.sys.Str.plus("Not a Func type: ", t)); +} + /************************************************************************* * ClosureFuncSpec ************************************************************************/ diff -r 56d95b6fa8ad src/sys/js/fan/MethodFunc.js --- a/src/sys/js/fan/MethodFunc.js Tue Sep 22 09:31:42 2015 -0400 +++ b/src/sys/js/fan/MethodFunc.js Wed Sep 23 01:39:57 2015 +0100 @@ -14,6 +14,7 @@ { this.m_method = method; this.m_returns = returns; + this.m_type = null; } fan.sys.MethodFunc.prototype.returns = function() { return this.m_returns; } fan.sys.MethodFunc.prototype.arity = function() { return this.params().size(); } @@ -27,8 +28,8 @@ if ((this.m_method.m_flags & (fan.sys.FConst.Static|fan.sys.FConst.Ctor)) == 0) { var temp = []; - temp[0] = new fan.sys.Param("this", this.m_parent, 0); - fparams = fan.sys.List.make(fan.sys.Param.$typeof, temp.concat(mparams)); + temp[0] = new fan.sys.Param("this", this.m_method.m_parent, 0); + fparams = fan.sys.List.make(fan.sys.Param.$type, temp.concat(mparams.m_values)); } this.m_fparams = fparams.ro(); } @@ -37,6 +38,20 @@ fan.sys.MethodFunc.prototype.method = function() { return this.m_method; } fan.sys.MethodFunc.prototype.isImmutable = function() { return true; } +fan.sys.MethodFunc.prototype.$typeof = function() +{ + // lazy load type and params + if (this.m_type == null) + { + var params = this.params(); + var types = []; + for (var i=0; i<params.size(); i++) + types.push(params.get(i).m_type); + this.m_type = new fan.sys.FuncType(types, this.m_returns); + } + return this.m_type; +} + fan.sys.MethodFunc.prototype.call = function() { return this.m_method.call.apply(this.m_method, arguments); @@ -44,13 +59,28 @@ fan.sys.MethodFunc.prototype.callList = function(args) { - println("### MethodFunc.callList"); - return this.m_func.apply(null, args.m_values); + return this.m_method.callList.apply(this.m_method, arguments); } fan.sys.MethodFunc.prototype.callOn = function(obj, args) { - println("### MethodFunc.callOn"); - return this.m_func.apply(obj, args.m_values); + return this.m_method.callOn.apply(this.m_method, arguments); } +fan.sys.MethodFunc.prototype.retype = function(t) +{ + if (t instanceof fan.sys.FuncType) + { + var params = []; + for (var i=0; i < t.pars.length; ++i) + params.push(new fan.sys.Param(String.fromCharCode(i+65), t.pars[i], 0)); + var paramList = fan.sys.List.make(fan.sys.Param.$type, params); + + var func = new fan.sys.MethodFunc(this.m_method, t.ret); + func.m_type = t; + func.m_fparams = paramList; + return func; + } + else + throw fan.sys.ArgErr.make(fan.sys.Str.plus("Not a Func type: ", t)); +}
Testing with testSys::FuncTest.testRetype() the only verifies that now fail are verifyEq(z.isImmutable, true) which relates to js: Func.toImmutable not implemented and this one:
testSys::FuncTest.testRetype()
verifyEq(z.isImmutable, true)
verifyEq(z.callOn("a", ["b", "c", "d", "e", "f", "g", "h"]), "abcdefgh") ... sys::Err: Test failed: bcdefghnull != abcdefgh
which I'm not too sure about, as it looks to me as if it shouldn't pass anyway!
I missed you a merged one here - can you sync up and test/update this patch so I can merge it correctly?
Sure, try this:
diff -r 108d631d7a58 src/sys/js/fan/Func.js --- a/src/sys/js/fan/Func.js Wed Sep 23 08:05:53 2015 -0400 +++ b/src/sys/js/fan/Func.js Wed Sep 23 13:40:23 2015 +0100 @@ -79,6 +79,20 @@ fan.sys.Func.prototype.toStr = function() { return "sys::Func"; } +fan.sys.Func.prototype.retype = function(t) +{ + if (t instanceof fan.sys.FuncType) + { + var params = []; + for (var i=0; i < t.pars.length; ++i) + params.push(new fan.sys.Param(String.fromCharCode(i+65), t.pars[i], 0)); + var paramList = fan.sys.List.make(fan.sys.Param.$type, params); + return fan.sys.Func.make(paramList, t.ret, this.m_func); + } + else + throw fan.sys.ArgErr.make(fan.sys.Str.plus("Not a Func type: ", t)); +} + /************************************************************************* * ClosureFuncSpec ************************************************************************/ diff -r 108d631d7a58 src/sys/js/fan/MethodFunc.js --- a/src/sys/js/fan/MethodFunc.js Wed Sep 23 08:05:53 2015 -0400 +++ b/src/sys/js/fan/MethodFunc.js Wed Sep 23 13:40:23 2015 +0100 @@ -66,3 +66,21 @@ { return this.m_method.callOn.apply(this.m_method, arguments); } + +fan.sys.MethodFunc.prototype.retype = function(t) +{ + if (t instanceof fan.sys.FuncType) + { + var params = []; + for (var i=0; i < t.pars.length; ++i) + params.push(new fan.sys.Param(String.fromCharCode(i+65), t.pars[i], 0)); + var paramList = fan.sys.List.make(fan.sys.Param.$type, params); + + var func = new fan.sys.MethodFunc(this.m_method, t.ret); + func.m_type = t; + func.m_fparams = paramList; + return func; + } + else + throw fan.sys.ArgErr.make(fan.sys.Str.plus("Not a Func type: ", t)); +}
Got it thanks - Func.retype fixed
Login or Signup to reply.
SlimerDude Fri 11 Sep 2015
Just to mention that currently there's no
bind()
orretype()
methods forFunc
in Javascript.bind()
I can often get away with by creating a new closure that call the original func with the new arguments. But I don't know a way aroundretype()
.andy Mon 21 Sep 2015
Ticket promoted to #2460 and assigned to andy
SlimerDude Tue 22 Sep 2015
An accumulated patch for
Func.retype()
, adding methods toFunc.js
andMethodFunc.js
:Testing with
testSys::FuncTest.testRetype()
the only verifies that now fail areverifyEq(z.isImmutable, true)
which relates to js: Func.toImmutable not implemented and this one:which I'm not too sure about, as it looks to me as if it shouldn't pass anyway!
andy Wed 23 Sep 2015
I missed you a merged one here - can you sync up and test/update this patch so I can merge it correctly?
SlimerDude Wed 23 Sep 2015
Sure, try this:
andy Wed 23 Sep 2015
Got it thanks - Func.retype fixed