When calling Func#callList I can get list of params through Func#params, I can determine if Param has default value or not (via Param#hasDefault), but I cannot keep default values if I don't want to override them.
For example:
class HttpResponse {
new make(Str body, Str contentType := 'text/plain', Int responseCode := 200)
}
It's needed in some heavy reflection-based code (dispatchers etc).
Maybe smth like Obj? Param#defaultValue?
brianTue 9 Nov 2010
I definitely understand your plight, but unfortunately the problem is that there is no such thing as a default value, rather it is a default expression.
So in some cases you actually have to have an instance and all the other parameters to actually figure out what the default should be. Here is a simple example:
class Foo
{
Str foo(Int x, Str y := "$this $x") { y }
Void main() { echo(foo(3)) }
}
tonskyTue 9 Nov 2010
Some kind of smart Func#call([Param:Obj] params) then maybe?
brianTue 9 Nov 2010
Maybe I don't understand your problem, but you know you can just leave off the arguments to call or callList which you want to fallback to the default?
In your example you are trying to keep a default in the middle of the argument list - you can't do that though (in either Fantom or via reflection).
tonskyWed 10 Nov 2010
Yes, that's exactly what I want — to keep default value in the middle of the arguments list. Is it possible to make it possible :) ?
brianWed 10 Nov 2010
Sorry, don't think it is really feasible. Consider what happens under the covers:
Void foo(Str a := "a", Str b := "b", Str c := "c")
Compiles into Java like this:
void foo() { foo("a", "b", "c""); }
void foo(Str a) { foo(a, "b", "c"); }
void foo(Str a, Str b) { foo(a, b, "c"); }
void foo(Str a, Str b, Str c) { ... }
So you can see that everything is pretty optimized based on parameter ordering. I have some ideas for named parameters and how that would work. But that is a future thing.
One "hack" you might try is to get the docs from the method via sys::Slot.doc. The documentation contains meta-data about the defaults used for display purposes. In the cast of literals this might be decodable. No guaratees of course, but will probably work for basic cases.
tonsky Tue 9 Nov 2010
When calling Func#callList I can get list of params through Func#params, I can determine if
Param
has default value or not (via Param#hasDefault), but I cannot keep default values if I don't want to override them.For example:
now I can do (last param kept defautl):
but I cannot do (override last but keep second):
It's needed in some heavy reflection-based code (dispatchers etc).
Maybe smth like
Obj? Param#defaultValue
?brian Tue 9 Nov 2010
I definitely understand your plight, but unfortunately the problem is that there is no such thing as a default value, rather it is a default expression.
So in some cases you actually have to have an instance and all the other parameters to actually figure out what the default should be. Here is a simple example:
tonsky Tue 9 Nov 2010
Some kind of smart
Func#call([Param:Obj] params)
then maybe?brian Tue 9 Nov 2010
Maybe I don't understand your problem, but you know you can just leave off the arguments to
call
orcallList
which you want to fallback to the default?In your example you are trying to keep a default in the middle of the argument list - you can't do that though (in either Fantom or via reflection).
tonsky Wed 10 Nov 2010
Yes, that's exactly what I want — to keep default value in the middle of the arguments list. Is it possible to make it possible :) ?
brian Wed 10 Nov 2010
Sorry, don't think it is really feasible. Consider what happens under the covers:
Compiles into Java like this:
So you can see that everything is pretty optimized based on parameter ordering. I have some ideas for named parameters and how that would work. But that is a future thing.
One "hack" you might try is to get the docs from the method via
sys::Slot.doc
. The documentation contains meta-data about the defaults used for display purposes. In the cast of literals this might be decodable. No guaratees of course, but will probably work for basic cases.