agiletortoise wrote:Right now, the Servoy method editor blocks the use of the "function" keyword (even in a literal string!).
True. However, the method editor does not block the use of the "Function" keyword. So....define your function using the
new Function constructor. A decent definition of how it is used may be found
here, about half-way down the page.
So, following is a simple add function example.
- Code: Select all
//adding
var add=new Function('a','b','return a+b')
application.output(add(8,3)) //returns 11
How about we create a function that is used in the definition of another function?
- Code: Select all
//any arithmetic operation
var compute=new Function('myOperator','return new Function("a", "b", "return a" + myOperator + "b")')
var multiply=compute('*')
var divide=compute('/')
var subtract=compute('-')
application.output(multiply(8,3)) //returns 24
application.output(divide(8,4)) //returns 2
application.output(subtract(8,3)) //returns 5
And now, what I read as your original need, prototyping. We'll extend Array's default functionality by writing a numeric sort funtion.
- Code: Select all
//prototyping any (established) object
Array.prototype.sortNum = new Function('return this.sort(new Function ("a","b","return a-b"))')
var tmp = [5,9,12,18,56,1,10,42,30,7,97,53,33,35,27]
tmp = tmp.sort() // returns alphabetical sort: 1,10,12,18,27,30,33,35,42,5,53,56,7,9,97
tmp = tmp.sortNum() // returns numerical sort: 1,5,7,9,10,12,18,27,30,33,35,42,53,56,97
A few considerations:
1. Since the actual body of the function is essentially a string (contained within quotes), if your body includes quotes, you need to be creative in stringing together your code in such a way that there is only one type of quote used in each substring, with the other type surrounding it. For example,
- Code: Select all
var copyStyles = function(destDoc, sourceDoc)
{
var links = sourceDoc.getElementsByTagName('link');
for(var i = 0; i < links.length; i++)
if(links[i].rel.toLowerCase() == 'stylesheet')
destDoc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
}
turns into
- Code: Select all
var copyStyles = new Function('destDoc', 'sourceDoc',
"var links = sourceDoc.getElementsByTagName('link');" +
"for(var i = 0; i < links.length; i++)" +
"if(links[i].rel.toLowerCase() == 'stylesheet')" +
"destDoc.write(" +
"'<link type=" +
'"text/css" rel="stylesheet" href="' +
"' + links[i].href + '" +
'">' +
"</link>');"
)
2. Functions defined using the constructor are generally compiled when invoked, which may lead to slower than optimal performance. Although I'm not sure how Rhino handles this.
3. Servoy clearly went out of their way to disable our abilitiy to use functions. Not that that is necessarily reason enough not to use them, it is just a 'warning'.
4. When prototyping, your additions to established objects are similar to globals in that they are persistent until you enter layout mode, quit servoy, etc.