TIP: how to use globals and scopes

use names scopes as much as possible, try to avoid putting everything in globals.js. This also means try to avoid having loads of globals.js files over modules
When you use scopes.myscope.xxx and scopes.myscope2.xxxx over your solutons and modules, so named according to what the code in that scope does, your developer and also runtime client will benefit from that.
This is because the standard globals scope is a combination of all globals.js files, this means for the developer that when you touch a globals,js file or use the globals scope ( (globals.xxx in code) we will have to read and parse all the globals files that are in your complete active solution. And this is just because you want to call 1 method a very small subset of what you really need.

At runtime when you have your globals scope accessed (which is always quite soon) the whole scope must be created with all the methods and variables already created. This could result in a huge hit (memory and cpu wise).

If you would just use scopes then small scopes are created at the moment they are accessed, so in a client when it doesn’t use the scope yet nothing is created and only when that client does access it (scopes.myscope2.xxxx) then we lazy create it and this will be then a much smaller set.
The same thing holds true for the developer, if you have in a forms.js file “globals.xxx” we need to create the fully globals scope (so all the files) to be able to resolve it (and give you code completion), but if you just use scopes.myscope.xxx then only 1 file needs to be parsed which only has a set of stuff that really belongs to that scope.

Also in all your files (i guess this happens more in globals files then in other scopes) don’t prefix it with itself…
So in a globals.js file avoid doing: globals.xxxx this is a useless indirection that only cost time (in developer but also in clients). globals.mymethod() can just be mymethod() because you are already in the globals file.
In the developer using this construct would mean double parsing and validation of the same file. Because the parser is parsing “globals.js” to validate the code but that code references then “globals.mymethod()” and that will only be resolved by parsing the file (when it already is doing this) again because it needs to have “mymethod”. If you just had mymethod() directly without the prefix the first parse would resolve it already just fine.

So the best thing to do is just open your globals.js files and do a search/replace on the prefix “globals.” and replace it with an empty string.

Thanks Johan, for this inside information! much appreciated!!

This:

Also in all your files (i guess this happens more in globals files then in other scopes) don’t prefix it with itself…
So in a globals.js file avoid doing: globals.xxxx this is a useless indirection that only cost time (in developer but also in clients). globals.mymethod() can just be mymethod() because you are already in the globals file.
In the developer using this construct would mean double parsing and validation of the same file. Because the parser is parsing “globals.js” to validate the code but that code references then “globals.mymethod()” and that will only be resolved by parsing the file (when it already is doing this) again because it needs to have “mymethod”. If you just had mymethod() directly without the prefix the first parse would resolve it already just fine.

So the best thing to do is just open your globals.js files and do a search/replace on the prefix “globals.” and replace it with an empty string.

is also the case for Servoy 6.0.9, where you don’t have scopes, right?

yes this hold true for any release of servoy that had already globals

oke, so even, if you jump from a globals file from one solution, to a global file in a module, don’t prefix?

no not needed because thats just one big file.

Look at the code completion if you do that so without the prefix, then you also already see methods of the other globals files.

oke, one final question (just to be sure) this also means not for only method, but also for global variables, right?

so in my globalmethod, I can do:

function myTest() {
   companyid = 1 
}

and where companyid is a global variable

Hi Johan,

Do you also suggest to place the module events in a seperate scope instead of in the global scope?

What do you mean with module events? But using as little of the globals.js as possible is the best way to do it.

I meant the solution events onOpen / onError.

Best practise I’d say is avoid using globals.js for anything but methods that should be deeplinkable (because only methods in the globals scope are accessible for deeplinking).

Anything else: create a dedicated scope for it. This also means creating a dedicated scope for your main solution, in which you put the stuff that is specific to your solution, like the onError or onOpen (if you don’t already have those in a module offcourse).

My 2 cents,

Paul

Good stuff.

I’m trying to understand the “scopes” concept… I have a solution and I’ve create a “mysolution” scope. In this scope I’ve create a text variable named ‘app_version’. The solution has a module, the module has a “mymodule” scope. In this scope I’m trying to create a variable named “app_version”, but I receive this error: “The name ‘app_version’ already exist as a scope variable”. So, can’t I create variables with the same name but in different scopes?

that sounds like a weird bug. having the same variables over multiply scopes should work just fine (except globals.xxx those are shared)

I’m using 7.3.0 rc

i just tried it and it works fine for me. I can add (through scripting directly typing it in the js file, or through the solex ->add variable) the “same” variable just fine.

This is the error I receive:

!ENTRY com.servoy.eclipse.model 4 0 2013-10-08 17:00:08.637
!MESSAGE Unexpected Exception
!STACK 0
com.servoy.j2db.persistence.RepositoryException: The name 'version' already exist as a scope variable
	at com.servoy.j2db.persistence.ScriptNameValidator.checkName(ScriptNameValidator.java:84)
	at com.servoy.j2db.persistence.ScriptVariable.updateName(ScriptVariable.java:82)
	at com.servoy.eclipse.ui.views.solutionexplorer.actions.EditVariableAction.run(EditVariableAction.java:147)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1410)

just give us steps how to reproduce it
Start with a clean solution

Ok:

  1. I’ve created a solution named “testSolution”, created a scope named “testsolution” and created a text variable named “testvar”.
  2. I’ve created a module named “testModule”, created a scope named “testmodule” and created a text variable named “testvar”. No error messages.
  3. Then, right click on “testvar” (of testModule), select “edit variable” and changed the value, then I’ve receive the error message: “…com.servoy.j2db.persistence.RepositoryException: The name ‘testvar’ already exist as a scope variable…”

but that’s different then what you started with, so you can create 2 variables just fine. Its just that changing it through the dialog a second time doesn’t work for you

Make a case then with the steps how you get that.

You’r right the error appears when editing, not when creating :oops:

case SVY-5226 created.