Declaring global variables/functions - use in many scripts

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Declaring global variables/functions - use in many scripts

Post by heyvern » Sun Mar 07, 2010 10:48 pm

Is it possible to declare truly "global" globals/functions? Or declare functions/commands in a card or stack script that can be accessed by other scripts? I am trying to make the scripts more efficient. In one situation I put in a loooong list of words into a string in a custom function and then check a variable to that list and return true or false if it is in the list. The list is created each time the function is called. I thought I could put that list in a global variable and use it throughout the application across many scripts but that hasn't worked for me so far. I tried the "openStack" and "openCard" commands without luck. I haven't tested with a standalone yet but when using the "Suspend Development Tools" in RR the openStack and openCard commands don't even run.

thanks for any help.

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Declaring global variables/functions - use in many scripts

Post by heyvern » Sun Mar 07, 2010 11:51 pm

Hah! Nevrmind.

It worked. Using "openStack" or "openCard" DOES declare the global variables. Working with the project open in RR and using the disable development tools does not send an "openCard" or "openStack" because it is ALREADY open in the application. Good to know this. I found out when I relaunched RR and BOOM the "put gMyglobal into message" popped up with all my global variables defined etc.

Is there a way to have RR send those commands, openCard or openStack during developement? I can type it into the message window but it would be nice if this could be "automatic".

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10043
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Declaring global variables/functions - use in many scripts

Post by FourthWorld » Mon Mar 08, 2010 3:59 pm

The startup message should be the only one you don't get in the IDE, since of course the IDE gets it when it starts. OpenCard, preOpenCard, etc. should all be sent.

If you find a repeatable recipe for this please post it to the RQCC as a bug:
http://quality.runrev.com/qacenter/
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Declaring global variables/functions - use in many scripts

Post by heyvern » Mon Mar 08, 2010 7:29 pm

I will see if I can reproduce it.

It was strange. I had the RR file open. I created a new stack script with the openStack command. It woldn't fire off. The variables it was suppose to create wouldn't show when sent to the message box and of course the application itself didn't work properly without those variables. After I quite RR and relaunched it I kind of forgot about that "put into message" bit of code I added to my openStack stack script (several hours had passed). When I opened my file it popped up in the message box and surprised me.

This is great. I have discovered I can put all of my commonly used globals, functions and commands in my stack script to keep things neat and tidy. I had been putting all my functions in the same "button" script and it was getting hard to read and keep track of things.

-----------------------------------

I do have a question though. In RR is it safe to load "important" global variables from an openStack script? Or would it actually be better to have a "hard copy" of those strings in a hidden field? Would it make more sense from a memory management aspect to just use the text from a field to loop through for comparisons? That way those globals don't have to stay in memory all the time? I could also create a table field for array storage of many string groups I need for extracting chunks from files.

I guess it "feels" as if the global variable lists are "ethereal" and "fragile" when they live in some sort of mysterious memory only plain of existence. ;) I sometimes think of variables when programming like some sort of bizarre multidimensional other worldly beings. ;)

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Declaring global variables/functions - use in many scripts

Post by heyvern » Mon Mar 08, 2010 8:11 pm

Figured it out.

If you create NEW global variables or change the openScript or openCardhandler after the file is already opened (and those handlers have fired off already) then the changes aren't activated. So it appears that the openCard, openScript handlers are not fired when using the "disable development tools" in RR. However there may be some sort of preference setting I haven't found that would change this behavior.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10043
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Declaring global variables/functions - use in many scripts

Post by FourthWorld » Mon Mar 08, 2010 8:23 pm

Globals actually take up far less space than storing the same data in a field, since the field object carries its own overhead for the object's structures.

If you need persistent storage between sessions, you could save to a field, or to a custom property, or to a text file. But at runtime, a global is hard to beat for both speed and size.

The one thing that makes some folks a bit skittish about globals is their ethereal nature: they can be modified by any handler at any time, requiring a bit of discipline to make sure you never have those values altered except when you want them altered.

The older I get the more I use accessors for things like that, commands and functions to write and read data completely independent of where that data is stored. This means I lose a fraction of a millisecond each time I call an accessor, but it helps keep the code clean, means I don't need to declare the global in the script using its values, and keeps the code separated from the data store in case I need to change the storage method down the road.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

gpearson
Posts: 84
Joined: Wed Feb 03, 2010 12:55 pm

Re: Declaring global variables/functions - use in many scripts

Post by gpearson » Tue Mar 09, 2010 8:17 pm

FourthWorld wrote: The older I get the more I use accessors for things like that, commands and functions to write and read data completely independent of where that data is stored. This means I lose a fraction of a millisecond each time I call an accessor, but it helps keep the code clean, means I don't need to declare the global in the script using its values, and keeps the code separated from the data store in case I need to change the storage method down the road.
As I am running into problems with global variables can you post a sample of what the code would look like from the above quote. One global variable I am trying to use is a WebServerService variable that would be set depending on the environment() of the application. If the environment is development then the gWebServerService would be set to "demo.weareclosedtoday.com" and if not then it would be set to "www.weareclosedtoday.com"
---
Graham Pearson
Goshen, IN USA

We Are Closed Today is your single internet resource for Indiana Area School Closings, Visit http://www.weareclosedtoday.com

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Declaring global variables/functions - use in many scripts

Post by heyvern » Wed Mar 10, 2010 4:39 am

Cool!

I just googled "accessors" and found something regarding programming in java that is pretty much the same for RR as well.

So the idea is to create classes/properties for the "objects" and use "get" to retrieve them. As you say they are "separate" from the "code". You don't have to use a bunch of custom functions to analyze strings etc. This will work great for my application. I can create different classes for all the "layers" in my document and keep them separate so I don't have to worry about strings that have similar "words" that conflict.

My application is set up to split a file format into many parts in an array. The "main" part of the file format is the "layers". There could be 50 layers or more. Each layer has sections with their own properties/classes that are always the same. Some layer types have similar properties etc.

You click on a layer in one field/window to display it's properties in other fields/windows. Would I have to apply classes to "objects" on screen like fields? Or can I give custom classes to "variables" or items in an array?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10043
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Declaring global variables/functions - use in many scripts

Post by FourthWorld » Wed Mar 10, 2010 6:23 pm

My reference to "accessors" was for something simpler, though I suppose you could also use custom props for such things, and many do.

To separate my data store from the code that uses it, I usually have functions and commands to get and set data in the store, as opposed to, say, working on global variables directly.

So rather than write:

Code: Select all

global gMyData
get line 2 of gMyData -- where line 2 is the user's name
...
I just write:

Code: Select all

 get UserName()
...and elsewhere in my message path (usually a library) I'll have the definition for that accessor:

Code: Select all

function UserName
  global gMyData
  return line 2 of gMyData
end UserName
The overhead of calling the function does mean it takes more time to execute, but that time difference is a fraction of a microsecond so in most cases it's well worth the expense in performance for what it does to help keep code more manageable.

If I need data obtained from an accessor in a repeat loop, I'll often get it once before entering the loop and use a local copy to keep that performance impairment from adding up:

Code: Select all

put UserName() into tUser
repeat 100
  DoSomethingWith tUser
end repeat
You could also use properties, and for many cases they're very handy, esp. when the data you're accessing relates to a specific object such as a custom control like the DataGrid. GetProp and SetProp handlers that can be very useful for invoking behavior in addition to obtaining and storing data.

But I tend to use custom properties sparingly, usually only for data bound to a specific object, for a few reasons.

First, being a lazy person (meaning "the less I type the faster I ship") this:

Code: Select all

get UserName()
...is simply easier to type than:

Code: Select all

get the uUserName of button "SomeObject" of stack "SomeStack"
Extra bonus points that I don't need to remember which object my data is stored in. :)

Even when the data is ultimately stored in a property, accessing it with a function or command frees me from needing to remember the object's descriptor, and usually means less typing.

Moreoever, using accessor handlers gives me the opportunity to change my storage entirely if I want down the road. For example, today I may be using custom props in a stack file as my data store (my favorite file format, so easy to work with), but later on I find that I need to migrate to using a database like SQLite. By using accessors I only need to change a handful of accessor handlers in one library script, and all of the code throughout the rest of my code base that uses them won't need to change at all, it'll just work.

Also, I've found that having a lot of getProp and setProp handlers in use in the message path can sometimes degrade performance of property accesses. Again, the difference is in fractions of a millisecond, sometimes fractions of a microsecond, but if I limit my use of getProp and setProp to those cases where I truly need data bound to an object then I feel I'm doing a reasonable job of saving up clock cycles I can later spend on features.

So much of these things are about tradeoffs, here between developer convenience and runtime efficiency. When I'm going to make a conscious decision to impair performance, I generally try to choose the option that will also improve my own human performance by requiring less typing.

Which data store and which means of accessing it is "best" will of course depend on the specifics of the task at hand. What I've described above are some general things I often do, but my code also has many exceptions to those as well.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

heyvern
Posts: 30
Joined: Sun Feb 21, 2010 12:38 am

Re: Declaring global variables/functions - use in many scripts

Post by heyvern » Wed Mar 10, 2010 8:39 pm

Great info FW.

I especially like the idea of changing the "store" to a database. The application I am creating is for project management for another application file format that doesn't have project management. I hope to be able to create an "online collaboration" server type project management using a database. So I can develop now for local use and then be able to change it later for use online. Currently I plan to save my own application files with project management data for local hard drive use. I can then change it to database storage at a later date.

This is great stuff. My head is spinning with ideas now to improve data access.

Post Reply