Servoy 6.0 alpha 5

rossent:

jbader:

When you use “instanceof” with the primitive datatypes, you get the automatic wrapper object for them

I do not see that, and have never heard of that. Do you see something different?

js> 'test' instanceof String

false
js> 4 instanceof Number
false
js> false instanceof Boolean
false
js>

I am not sure how you got your results, but they really are not the right thing expected. See the attachment from the interactive console.
Regarding the transient wrapper objects for the primitive datatypes in JavaScript - the best explanation which I have seen is in the book “JavaScript: The definitive Guide” by David Flanagan - there is a whole chapter on them.

Transient wrapper objects occur when you treat a primitive like an object. e.g. if you call .length() on a primitive string. What happens in those cases is a new String object is first created from the primitive itself, then length is called on the resulting String object. The String object is then sent to garbage collection, but the original primitive remains untouched!

As far as why you and I see different things I find your output most interesting b/c you are using the console in Servoy and I am using raw rhino at the command line (but the same Rhino version mind you).

I’ll have to try this all in Servoy specifically.

In interesting conversation though I must say.

@Servoy…is strict mode on or off in Servoy’s JS implementation?

If the left-hand side of the instanceof operator is not an object but a primitive, it should return false (like the results which you are seeing in raw Rhino)

In Servoy, for some reason they get “elevated” to objects (by an intrinsic wrapper object) and we get the results which you see in the Interactive Console screen shot.

Trying the same in a browser for example, matches what you see in Rhino. Try it with a simple test like this:

<html>
    <head></head>
    <body>
        <span onclick="javascript:if(4 instanceof Number){alert('TRUE');}else{alert('FALSE');};">Click Here To Test</span>    
    </body>
</html>

@Servoy, is the below intended or somewhere documented? It makes assertion and explicit type checking pretty tough!

In Servoy, for some reason they get “elevated” to objects (by an intrinsic wrapper object) and we get the results which you see in the Interactive Console screen shot.

@Rossent
Thanks for the extra testing!

yes i checked it out and this is a patch that we have in rhino for a long time (at least since servoy 3.5)
the thing is that rhino itself has even comments in the code, this is the code in rhino:

        // for primitive values on LHS, return false
        // XXX we may want to change this so that
        // 5 instanceof Number == true
        if (! (a instanceof Scriptable))
            return false;

and in servoy it is:

                // for primitive values on LHS, return false
		// XXX we may want to change this so that
		// 5 instanceof Number == true
		if (!(a instanceof Scriptable))
		{
			Scriptable converted = ScriptRuntime.toObject(cx, cx.topCallScope, a);
			if (converted != null)
			{
				a = converted;
			}
			else
			{
				return false;
			}
		}

The thing is that in java code of rhino there are no primitives …
Everything is just the object it has to be because the Scriptable.put() objects must have an object

The stupid thing is that i think the way servoy works is what i expect to happen
Because

var myNumber = 1;
if (myNumber instanceof Number) fixed = myNumber.toFixed(1)

That just works in servoy, as i would expect that it should work…
And i can call all number methods just fine on it also.
So it is a number…
I can even prototype it:

Number.prototype.myFunction = function(){}
var myNumber = 1;
myNumber.myFunction()

jbader:

jcompagner:
yes i think that typeof is just strange…
dont know why you would really us that

typeof is necessary to discover datatypes.

	function MyObject() {
		
	}
	
	var x = new MyObject();
	
	application.output(typeof(x));
	
	application.output(x instanceof MyObject);
	
	application.output(x instanceof String);

i still don’t think typeof really doesnt give me anything in the example above
yes it says “object” … that i know…
But it doesn’t say what object it is… That is instanceof way better.
Besides that typeof returns a string which i find horrible… Because that means no checks at “compile” time at all.
the instanceof operator can really be used to check a type and that type on the rhs can be checked by tooling.

also your stuff:

var x = new Boolean(1);
application.output(typeof(x));

that gives you object… And then what?

@Johan

Now I completely understand what I was seeing. Thank you for sharing the Java code, now I get it (although I can’t say I’m a fan of it). :?

But regarding your comment about you being able to call the methods of Number from a number (primitive), that is supported in JS (w/o your Java hack) and is intended, but it doesn’t mean that you are necessarily dealing with a Number vs a number. It just means that JS has temporarily converted your number to Number as opposed to throwing an exception. It takes loose typing to a whole new level; dynamically generating a Number from your primitive to allow you to use the Number object’s props and methods! It’s a crazy feature, but it is a known one.

For example the following will work just fine even though the variable myNumber is a primitive:

var myNumber = 1;
myNumber.toFixed(1);

But at least now I understand this, so again thanks a lot!

PS you do realize how hard this makes explicit type checking and assertions in unit testing right?

jcompagner:

jbader:

jcompagner:
yes i think that typeof is just strange…
dont know why you would really us that

typeof is necessary to discover datatypes.

	function MyObject() {
}

var x = new MyObject();

application.output(typeof(x));

application.output(x instanceof MyObject);

application.output(x instanceof String);



i still don't think typeof really doesnt give me anything in the example above
yes it says "object" ... that i know...
But it doesn't say what object it is... That is instanceof way better.
Besides that typeof returns a string which i find horrible.. Because that means no checks at "compile" time at all.
the instanceof operator can really be used to check a type and that type on the rhs can be checked by tooling.

also your stuff:



var x = new Boolean(1);
application.output(typeof(x));




that gives you object.. And then what?

My point was that you need both. typeof should be used to discover which primitive datatype you are working with, if you are working with a primitive. Instanceof should be used [only] when you have an object and want to know what type of object it is.

jbader:

var myNumber = 1;

myNumber.toFixed(1);

That example is what i gave to give you a piece of code why i think instanceof should work on that…
Because you can call all methods of that Number type you check for on it!
So purely looking at myNumber from a higher point of view it is a Number …
It doesn’t really matter how you declared it…

jbader:
PS you do realize how hard this makes explicit type checking and assertions in unit testing right?

No not really can you give me an example why it makes it hard?

But i tested some more and came to a conclusion that some pieces of javascript are just weird:

var x = true
var y = true
alert(x == y); // TRUE

var x = new Boolean(true)
var y = true
alert(x == y); // TRUE

var x = true
var y = new Boolean(true)
alert(x == y); // TRUE

var x = new Boolean(true)
var y = new Boolean(true)
alert(x == y); // FALSE?????

that is just weird…

jbader:
My point was that you need both. typeof should be used to discover which primitive datatype you are working with, if you are working with a primitive. Instanceof should be used [only] when you have an object and want to know what type of object it is.

and currently in servoy that is not needed if you don’t want to use it, you can always use instanceof…
And in my point of view that is way more correct behavior…
But of course you can always use typeof because that is not behavior that is changed right? typeof is “object” for all objects and boolean or number for “primitives”
so you can do:

if ( typeof(myobject) == "object")  {
    if (myobject instanceof String) {

    }
    else if (myobject instanceof MyObject) {

    }
}
else  {
 // primitive
}

besides this, in servoy you have all kind of data coming in and out of the script runtime
What should all those be?
in java they are not primitives … They are all objects (Integer,Long,String,Date,Double)

jcompagner:

jbader:

var myNumber = 1;

myNumber.toFixed(1);

That example is what i gave to give you a piece of code why i think instanceof should work on that…
Because you can call all methods of that Number type you check for on it!
So purely looking at myNumber from a higher point of view it is a Number …
It doesn’t really matter how you declared it…

jbader:
PS you do realize how hard this makes explicit type checking and assertions in unit testing right?

No not really can you give me an example why it makes it hard?

But i tested some more and came to a conclusion that some pieces of javascript are just weird:

var x = true

var y = true
alert(x == y); // TRUE

var x = new Boolean(true)
var y = true
alert(x == y); // TRUE

var x = true
var y = new Boolean(true)
alert(x == y); // TRUE

var x = new Boolean(true)
var y = new Boolean(true)
alert(x == y); // FALSE???




that is just weird...

I see your point about number vs Number in the example we both gave. What is the point afterall in having the primitive at all if you can use the Number object’s properties and methods on the fly without an exception being thrown. I certainly would agree that makes even having a primitive fairly useless. But the fact is that it is there and that is just how it works.

Regarding an example of why it makes explicit type checking dificult consider…

/**
* Do something.
*
* @param {number} n A number primitive.
*
*/
function doSomething(n) {
	// Explicit type checking
	if(typeof(n) !== 'number') {
		throw new TypeError('N must be of type number.');
	}
	else {
		// Turn off the city's powergrid.
	}
}

In the above example if n were defined as follows in scripting…

var n = 10;

Then the result of typeof above would be ‘number’ and the city’s powergrid would be turned off.

If however it were defined as follows (also in scripting)…

var n = new Number(10);

Then the result of typeof above would be ‘object’ and the city’s powergrid would not be turned off.

Now if the parameter n were passed into the function from Servoy’s Java code/not defined in scripting it would in fact be a Number object, but would also pass the typeof check(!) b/c from what I can tell you have somehow made n both Number and number.

So you might be thinking well sure, but who cares at the end of the day it’s the number 10…and yeah, you are right, but the fact is I can’t explicitly check it and determine what it really is.

Finally regarding all of the other examples the trouble with those are that you are checking falsy and truthy values, which you should never do in JS unless you mean to. The general rule is to ALWAYS use === unless you are purposely checking all falsy or truthy (or so says Crockford). In JS truthy and falsy values are strange indeed. Change your ‘==’ to ‘===’ and everything will change.

jbader:
In JS truthy and falsy values are strange indeed. Change your ‘==’ to ‘===’ and everything will change.

No then the values are also of the truth

i see === as what in java == is (ok not completely the same but close)
and i see == what in java for the most part object.equals() is…
And that is what you want…
In java on objects we almost never use == (so === in js) but almost always .equals() (so == in js)

Because normally you always want to have content equals not object same instance equals…
But a real content equals you don’t really have in js i believe.

But in java you have this:

String str1 = new String(“jeff”);
String str2 = new String(“jeff”);

str1.equals(str2) (== true and that is what most people expect…)

jcompagner:

jbader:
In JS truthy and falsy values are strange indeed. Change your ‘==’ to ‘===’ and everything will change.

No then the values are also of the truth

i see === as what in java == is (ok not completely the same but close)
and i see == what in java for the most part object.equals() is…
And that is what you want…
In java on objects we almost never use == (so === in js) but almost always .equals() (so == in js)

Because normally you always want to have content equals not object same instance equals…
But a real content equals you don’t really have in js i believe.

But in java you have this:

String str1 = new String(“jeff”);
String str2 = new String(“jeff”);

str1.equals(str2) (== true and that is what most people expect…)

I think that is not a great comparison when in JavaScript you can do things like…

js> var s = '1';
js> var n = 1;
js> s == n
true
js>

.equals in Java requires that the Object you are comparing to be of the same type as the object from which you are calling the equals method.

Anyhow I think there would be a lot of value in not deviating from JavaScript’s standard too much (recently noticed that Paul made a similar comment on standards here: http://forum.servoy.com/viewtopic.php?f=13&t=15704&p=84444&hilit=constants#p84481), particularly if new features are being introduced which seemingly do some type checking in the editor. If the type checking does not conform to the JavaScript standard (or any known JavaScript standard) that will be quite confusing (especially when the mods to Rhino are unpublished)!

In my opinion the following should show a warning in the editor…

/**
* Do something.
*
* @returns {number}
*/
function doSomething() {
	return new Number(10);
}

6 really looks very neat though, and it’s obvious a lot of great work has been done.

Thanks

Using directly the constructors new Number(x), new String(x) and new especially new Boolean(x) is very seldom needed. JavaScript does that for you silently when necessary.

Beware of this classical case explaining the differences between the primitives and objects:

function someMethod()
{
	var x = false;
	var test1 = x ? 'What?!' : 'Duh!';
	application.output('Test 1: ' + test1);
	
	var y = new Boolean(false);
	var test2 = y ? 'What?!' : 'Duh!';
	application.output('Test 2: ' + test2);
	
	var n1 = 0;
	var test3 = n1 ? 'What?!' : 'Duh!';
	application.output('Test 3: ' + test3);
	
	var n2 = new Number(0);
	var test4 = n2 ? 'What?!' : 'Duh!';
	application.output('Test 4: ' + test4);	
}

Using new Boolean(x) is a big no-no! And I would argue that you should never use new Number() either.

On a separate note, I think that when it comes to 3 instanceof Number Servoy should throw an exception since this is the standard (if someone needs that to evaluate to true, they will have to use the Object() function like Object(3) instanceof Number)

One more case where the code inspection is not working correctly:

/**
 * @return {Boolean}
 * @properties={typeid:24,uuid:"8F038E5F-54EE-4637-B383-3A4FF02DF108"}
 */
function firstMethod() 
{
	var x = 10;
	var y = 20;
	if(x > 1)
	{
		//this generates the warning:
		//"Function firstMethod declares Boolean as type but returns Number"!
		return (y > 5);
	}
	//this then generates the warning: 
	//"Return statement returns Boolean which is inconsistent with the previous return Number"
	return false;
}

Should we be able to remove at runtime from the solutionModel forms which have been created at design time?

For example:

var _removed = solutionModel.removeForm('someFormCreatedInServoyDeveloper');

Currently, this is possible and I can think of a scenario where it might be used - for example, at runtime depending on user license, remove from the application certain functionality. The problem is that such removal is a really drastic measure and any code which uses things like:

forms.someFromCreatedInServoyDeveloper.doSomething();

will get exceptions similar to “cannot call doSomething of undefined”.

Can the solutionModel.removeForm be modified to either not remove forms created at design time with Servoy Developer (simply return false) OR add an optional second argument like solutionModel.removeForm(formName, [removeOnlyRuntimeForms]) which controls whether design-time forms can be removed or not (by default, removeOnlyRuntimeForms will be false so the current behavior is not changed)? I personally prefer the second option since it provides more functionality.

So what have I missed this time?
I exported a solution from Servoy 5.2.6 and attempted to import in 6a5. I get the message to enter the password because it is protected solution. Which it is not.
I use the developer to do the import.
The 6a5 is a brand new install, repository is brand new (the Postgres is the one bundled with Servoy).
Using Win Xp Pro Sp3.

JSMethod has the property showInMenu, however the create method dialog does not have the option anymore to set that property.
Is this deprecated now? Can we still use it?

Hi all,

We are experiencing an issue with tab panels running in the web client. Basically we add tabs to the tab panels dynamically at run-time. However in the web client you cannot switch between the tabs - clicking on any tab different than the currently active one results in the indicator showing up “Loading…” and nothing else happens. Also when tabs are removed from the tab panel, removing the last one results in an “Internal Server” error page displayed. The default Servoy navigators on such dynamically added tabs also do not work in the web client (the same “Loading…” indicator and nothing else happens) if you click the next/previous buttons. However entering a record index in the entry field and pressing Enter does navigate correctly. It seems as if there is an issue with the Ajax calls or something like that.

More info: when we add the tabs, we provide all arguments to the addTab method and the tabs are added without any problems. The issue is present only when running in the web client - the smart client works fine. This appears to be an issue introduced in a5 since a4 worked correctly.

Any assistance on this is greatly appreciated!

rossent:
…We are experiencing an issue with tab panels running in the web client…

Turns out the issue applies even if the tabs are added statically at design-time. Renders the web client unusable for us.

Submitted case 364621 along with a sample solution demonstrating the issue. In my opinion this should be escalated with highest priority and hopefully fixed with the next release.