I have always assumed that parameters for custom functions are passed strictly “by value”: if you point to a field, then that field’s value is what the custom function receives. Look at the example below. The custom function is very simple and just returns the value of the parameter. I am calling the custom function and pointing it to a field for the parameter. Works exactly like you’d expect it to, doesn’t it? The custom function just returns the parameter that we passed in.
Now let’s change the custom function to return two lines:
- the value of the parameter and
- a getfieldname( ) function call on the parameter
When looking at the result in the Data Viewer we see that the result is both the value and the field name.
That seems to indicate that the parameter is not really the value of the field, but a reference to the field itself. That means that inside the custom function we have access to a field’s value but also any other information we can ask for by knowing the field’s name (through the Design functions for instance).
Scripts can also receive a parameter. Does the same thing apply to scripts then? If I specify a field as the script’s parameter, do I get just the value or also the reference to the field? Let’s try. Below is a one-line script that displays a custom dialog with the result of using the getfieldname( ) function on the script’s parameter:
When we call that script from a button that passes in a field as the parameter, the message displayed is “?”.
It does not work here. The “?” is what you get when you use the getfieldname( ) function on something that is not a field. A script just receives the value of the field, not a references to the field. So script parameters are strictly “by value”, custom function parameters are “by reference” when the parameter points to a field. Food for thought…
In the next blog post I’ll show an example of how we can use that “by reference” behavior of custom functions to our advantage.
Thank you for your sharing, wim. This is very interesting and evelating.
Glad you liked it, Cliff.
Great tidbit here, thanks for sharing. I never knew this was the case but I can already begin to see some very useful situations to use it for, thanks again! (this now seems make the GetNthRecord function make sure sense, being you pass it what appears to be a field value, yet it treats it as a reference)
Thanks, Daniel. Looking forward to reading about how you will use it 🙂
As a potential use, we looked as a team at building some custom functions that work similar to the aggregates, but can be passed a range of records, eg:
SumRange ( Field ; Start ; End )
ListRange ( Field ; Start ; End )
the start and end is a record # to begin and end at – which can be used either via relationship or on a found set. The functions would use recursion and each iteration would make use of GetNthRecord function which is passed “Field” along with a number of the recursion.
One thing we noted was that GetNthRecord doesn’t like working with other aggregate functions, so in the case of SumRange, we could not use the Sum function within the recusion along with GetNthRecord , instead we had to concatenate the results using + , similarly for List we had to use ┬╢ to get the desired result, weird!
Yes, very interesting, thank you Wim ! i went from a recent posted FM Community post. Wanted to add i recently discover a similar shade with Calculation variables (without $). Also they store a reference instead a value.
Sincerly,
Fred
Thank you Wim.
I have discovered a similar difference with Let variables (without $). They are storing a reference whereas other variable are storing values.
Fred
I wrote about this a while back
https://www.geistinteractive.com/2013/08/04/what-does-getfieldfieldname-return/
It is very handy
Todd