I was made aware of a feature of call_out that I didn't know about: if the object that the callback function belongs to is destructed before the call_out is supposed to be executed, the call_out is silently ignored.
But with Function.curry, this is not the case. Instead you get an error message.
Here is a demo program:
---cut here--- #!/usr/bin/env pike
class X { void work(int x) { werror("got work %d\n", x); } }
int main(int argc, array(string) argv) { X x = X(); call_out(x->work, 1, 1); if (argc > 1) call_out(destruct, 2, x); call_out(x->work, 3, 3); call_out(Function.curry(x->work)(4), 4); call_out(exit, 5, 0); return -1; } ---cut here---
Run it with no arguments to see what happens when the object isn't destroyed:
$ ./test.pike got work 1 got work 3 got work 4
Run it with any argument to trigger the destruction of x. Notise how you don't get any error for the 3-second callback, but the 4-second currified callback gives an error:
$ ./test.pike 1 got work 1 Cannot call functions in destructed objects. Unknown program: destructed object->function(4) server/pike/8.0.469/lib/modules/Function.pmod:85: Function.__lambda_65958_5_line_85() -:1: Pike.Backend(0)->`()(3600.0)
Would it make sense to have Function.curry also ignore calls to destructed objects? The change is trivial:
diff --git a/lib/modules/Function.pmod b/lib/modules/Function.pmod index 8a5498c483..d0b4a65335 100644 --- a/lib/modules/Function.pmod +++ b/lib/modules/Function.pmod @@ -83,7 +83,7 @@ function(mixed...:function(mixed...:mixed|void)) curry(function f) { return lambda(mixed ... args1) { return lambda(mixed ... args2) {
return f(@args1, @args2);
}; };return f && f(@args1, @args2);
}
In either case, I think this ought to be documented here: http://pike.lysator.liu.se/generated/manual/modref/ex/predef_3A_3A/Pike/__Ba...