saving environment for debugging purposes

Thank you for the script and the learnings.

It works great.

I guess from what you said…

…that it is not possible to extend the scope of a variable outside an handler

I also see that i was near your solution but that by trying to optimize it (not having to retype the variables names in the recover routine), i spent a lot of time without going nowhere
So i also learnt that lazyness is not always the best advisor !
Thanks again

It actually is possible to use variables outside the scope of handlers. Therefore you have to declare the variables global. There are two types of variables in general: global ones and local ones. You declare them like this:

local aLocal
global aGlobal

Variables are local by default, so you shouldn’t declare one as a local unless you declared it as a global first.

set v to 1 -- a local variable

global v
set v to 2 -- the global version of v

local v -- switch back to the local one
display dialog "Local v is " & v
--> 1

global v -- switch back to global
display dialog "Global v is " & v
--> 2


If you want to use the global variable, make sure you let AppleScript know you want to use the global one:

on run
global v
set v to 1
displayV()
--> 1

setV(3)
displayV()
--> 3

local v -- switch to local v
set v to 5
display dialog "Local v is " & v
--> 5

displayV()
--> 3
end run

on displayV()
global v
display dialog "Global v is " & v
end displayV

on setV(newV)
global v
set v to newV
end setV

I hope you get the concept of global variables at least a little bit know,
ief2

PS: I’ve written this post on my iPod so please excuse me for my bad spelling. It’s due to the fact that my first language isn’t English and the iPod doesn’t have a good spelling checker. Also excuse me for the bad AppleScript alignment. But since I’m on my iPod, there’'s now way to compile scripts and no easy way to insert a tab.

EDIT: I guess there’s something wrong with the copy/paste function of the iPod Touch. Line endings did not come through in this post. Click “Quote” to see full post. (Can someone explain why my post looks so weird?)

Either way, you still have to type as much.

That’s right. It’s much better to let your handlers return something than making a mess of local and global variables.

@ief2

Thanks for your answer
However i am not sure i could use it to fulfill the initial request

  1. i woud have to make global a variable that was not defined as such (which may be an acceptable price to pay)
  2. i still don’t get how i could access the name of the variable (as opposed to the content) for use in the recovery phase

Something like:


set variable1 to "Hello."
set variable2 to "How are you today?"
set list_of_variables to magic_function( {variable1, variable2,...}) -- where magic_function captures both the strings "variable1" and the content of variable1

save_environment(list_of_variables) --saves to disk

recover_environment() -- can reinitialise "variable1" to the saved content of the old variable1, which i guess is where i would need global variables



{variable1, variable2}

I would think to stick with my idea. Having globals means the script is not flexible, and you have to change it each time you put it into another script.

@Dylan

That’s precisely what i want to avoid by trying to code a reference to the name of the variable, but maybe it is not possible

Anyway, i did use your idea for my needs, so thanks again

In normal scripting files, it’s of course better to use a return value in your handlers. Globals are mostly used if there are other handlers than the on run (like on idle, on open theObjects, on quit).

A little demonstration:

global idleCount

on run
	-- set up idleCount
	-- else you'll get the error "the variable idleCount is not defined"
	-- in the "on idle"-handler
	set idleCount to 1
end run

on idle
	set myBut to missing value
	set myBut to button returned of (display dialog "This dialog has already been displayed for " & idleCount & " times" buttons {"Quit", "OK"} default button 2 giving up after 1)
	
	-- Quit
	if myBut is "Quit" then quit
	
	-- increase idleCount via handler
	-- is the same as
	-- set idleCount to idleCount + 1
	increaseIdleCount()
	
	return 1
end idle

on increaseIdleCount()
	set idleCount to idleCount + 1
end increaseIdleCount

Hope it helps,
ief2

hello ief2

Given a variable var_1,

       set var_1 to "my precious data"

Would you know a way to achieve either:

1) a way to get the name of the variable
i.e
my_routine(var_1)

returns the string “var_1”

2) a way to address the content of a variable by its name as string
i.e
my_routine(“var_1”)

returns “my precious data”"

I looked into the AS guide, to no avail

As far as I know, it’s not possible to do such things. For the second one you could do something like:

getVarWithName("var")

on getVarWithName(aString)
	set myScript to "get " & aString
	return (run script myScript)
end getVarWithName

But then again, how would you pass the value of “var” to the script? I don’t know, and I don’t think any of us knows.

If your above script worked, i think i may have had a solution

But it seems it does not work, even if global

global MyVar

set MyVar to "test"

getVarWithName("MyVar")

on getVarWithName(aString)
	set myScript to "get " & aString
	return (run script myScript)
end getVarWithName

→ returns “Variable MyVar is undefined”

There’s a problem of heritance i can’t solve

To be clear: my script does not work!

The script stored in myScript is completely different than the script which creates it. It does not share any variable.

So you will need to pass the variable to the handler in the normal (and only) way:

global theGlobalVar

set theGlobalVar to "test"
display dialog getVar(theGlobalVar)

on getVar(aVar)
	return aVar
end getVar

Thanks for the answer, i’ve understood the concept of global variable

What i do not see is:

  • how it answers my request ("Would you know a way to achieve either: 1. … or 2. …) ?
  • what you meant by “For the second one you could do something like…”

I tried to explicitely make heritance possible, but it does not work either

global MyVar
global thisScript

set thisScript to me

set MyVar to "test"

getVarWithName("MyVar")

on getVarWithName(aString)
	set myScript to "get " & aString
	
	script myScript2
		property parent : thisScript
		run script myScript
	end script
	
	return (run script myScript2)
end getVarWithName

→ returns “Variable MyVar is undefined”

I have now idea what you mean with this. Just place global aVar in your script if you want to access the global variable.

I don’t think this is possible

See my PM
Thanks

Yahoo.
I found a way to do it (here http://macscripter.net/viewtopic.php?id=24559)

set var to {1, 2, 3, 4, 5}
evaluate("var") --> {1, 2, 3, 4, 5}

to evaluate(theThing)
	run script "on run {x}
return x's " & theThing & "
end" with parameters {me}
end evaluate

As a consequence i have found a solution for the above problem, i 'll post in code exchange

here it is :
http://macscripter.net/viewtopic.php?pid=127240

I get it! I’ll use this any day: :smiley:

set myvariable to {string:"83IFN93", number:2, name:"Code"}
evaluate("myvariable") --> {string:"83IFN93", number:2, name:"Code"}

to evaluate(theThing)
	try
		run script "on run {x}\nreturn x's " & theThing & "\nend" with parameters {me}
	on error e number n
		display dialog "ERROR: \"" & e & "\" NUMBER: " & n buttons {"OK"} default button 1
	end try
end evaluate

…damned !

I can’t believe it. :rolleyes:
I was so focussed on trying to get access to the variable names that i did forget what i wanted to do at the first place.

The program i came by with works, but it is just a loosy declination of the one of Dylan Weber.

To make it better

  1. the save_environment part should also store the name of the variable (pretty easy, now that we have “evaluate”)
  2. The recovery part should be simplified as a no parameters function to save some editing
    recover_environment()
    that should set the variables internally, but as Dylan and ief2 put it this is not possible without using global variables (and even so, not so sure…), which is a bit awkward.

i still have some homework…

Here is something that can help: saving without a file.

 property x : ""
on run
	script o
		property l : x
	end script
	set thetext to text returned of (display dialog x default answer "")
	if x is o's l then
		set x to thetext
	end if
end run