extendscript object is invalid - extendscript
InDesign scripting question.
I know what need to write with var. I just try to understand what happen...
There is my script:
function myalert(s){
var w = new Window('palette')
ws = w.add('statictext',undefined,s)
w.show()
$.sleep(1000)
w.close()
}
myalert('hello')
alert(ws)
alert:
1. [Object StaticText]
2. JavaScript Error! Object is invalid...
Question: why this happen? Why error after alert? ws already deleted from memory? Then why I see alert? Not deleted? Then why I see error?
First myalert() executes and you see 'hello' alert.
Then myalert() finishes and ws gets deleted along with w (which is local to myalert()).
Then you try accessing ws in global scope - after it was deleted - and get the error.
See:
var w = 100 // global
function myalert(s){
var w = new Window('palette') // local (shadows 100)
ws = w.add('statictext',undefined,s) // global
w.show()
$.sleep(1000)
w.close()
alert('In myalert() w = ' + w)
alert('In myalert() ws = ' + ws)
}
myalert('hello')
alert('Global, w = ' + w)
alert('Global, ws = ' + ws)
If you don't use var, both w and ws will stay in global scope:
function myalert(s){
w = new Window('palette')
ws = w.add('statictext',undefined,s)
w.show()
$.sleep(1000)
w.close()
alert('[myalert] w = ' + w)
alert('[myalert] ws = ' + ws)
}
myalert('hello')
alert('[global] w = ' + w)
alert('[global] ws = ' + ws)
PS. You can also dump objects on console with $.writeln('ws = ' + ws)
Related
Nodejs indexOf with array of arrays
I'd be grateful if someone can explain what I'm doing wrong here. I compare two arrays of geographic coordinates, successfully find the common elements and then try to get the indexes for the first hit. Only arrB works as expected. Although the key is quite clearly at arrA[1], no match is found. I've included loads of logging because I don't quite believe what I'm seeing. function arrayIntersect(a, b) { /* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */ var aa = {}; a.forEach(function(v) { aa[v]=1; }); return b.filter(function(v) { return v in aa; }); } const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]] const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]] console.log(arrA.length + ' ' + Array.isArray(arrA)) console.log(arrB.length + ' ' + Array.isArray(arrB)) console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries console.log(arrB[0].length + ' ' + Array.isArray(arrB[0])) res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res)) let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key)) let idxA = arrA.indexOf(key) ; console.log('idxA ' + idxA) let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB) Results Server started at http://localhost:8080 28 true 53 true 2 true 2 true res 53.7,-2.45,53.93,-2.77,53.66,-2.75,53.62,-2.96 true key 53.7,-2.45 true idxA -1 idxB 13
When you use arrays with objects in it the indexOf function compares then the object reference and not the object itself to get the index value. And remember, in your case you have arrays in arrays but in javascript also arrays are objects so this aplies as well in your case. Then your arrayIntersect function filters arrB, therefor the originale objects from arrB are stored then in the res array which then only can be used to get back the index in the arrB. One approach could be to just use find for arrA to get the index and just stringify the objects while comparing: function arrayIntersect(a, b) { /* credit https://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript */ var aa = {}; a.forEach(function(v) { aa[v]=1; }); return b.filter(function(v) { return v in aa; }); } const arrA = [[53.88,-2.96],[53.7,-2.45],[53.79,-2.52],[53.66,-2.61],[53.98,-2.34],[53.92,-2.36],[53.89,-2.95],[53.9,-2.94],[53.88,-2.4],[53.89,-2.81],[53.93,-2.77],[53.87,-2.13],[53.9,-2.54],[53.6,-2.91],[54.01,-2.83],[53.83,-2.44],[53.6,-2.88],[54.02,-2.76],[53.99,-2.8],[54.15,-2.79],[53.85,-2.13],[53.62,-2.96],[54,-2.84],[53.66,-2.75],[53.91,-2.27],[53.86,-2.62],[53.51,-2.13],[53.82,-2.3]] const arrB = [[53.82,-2.9],[53.95,-2.73],[53.62,-2.73],[54.11,-2.81],[54.18,-2.84],[53.53,-2.09],[53.83,-2.98],[53.87,-2.42],[53.82,-2.66],[53.87,-2.41],[53.88,-2.98],[53.96,-2.75],[53.53,-2.02],[53.7,-2.45],[54.06,-2.87],[53.94,-2.34],[53.7,-2.87],[53.61,-2.89],[54.18,-2.84],[54.12,-2.8],[53.86,-2.82],[53.9,-2.53],[53.91,-2.86],[53.81,-2.26],[53.8,-2.51],[53.79,-2.98],[53.79,-3],[53.74,-2.92],[54.11,-2.8],[53.96,-2.49],[53.89,-2.44],[53.87,-2.12],[53.93,-2.77],[53.93,-2.78],[53.86,-2.86],[54.14,-2.46],[54.08,-2.78],[54.07,-2.75],[53.94,-2.86],[53.78,-3],[54.02,-2.89],[53.86,-2.26],[53.68,-2.79],[53.66,-2.75],[53.66,-2.88],[53.78,-2.79],[53.66,-2.31],[53.67,-2.3],[53.6,-2.08],[53.63,-2.09],[54.16,-2.83],[53.62,-2.96],[53.84,-2.15]] console.log(arrA.length + ' ' + Array.isArray(arrA)) console.log(arrB.length + ' ' + Array.isArray(arrB)) console.log(arrA[0].length + ' ' + Array.isArray(arrA[0])) // sample entries console.log(arrB[0].length + ' ' + Array.isArray(arrB[0])) res = arrayIntersect(arrA, arrB) ; console.log('res ' + res + ' ' + Array.isArray(res)) let key = res[0] ; console.log('key ' + key + ' ' + Array.isArray(key)) let idxA = arrA.indexOf(arrA.find(el=>JSON.stringify(el)===JSON.stringify(key))) ; console.log('idxA ' + idxA) let idxB = arrB.indexOf(key) ; console.log('idxB ' + idxB)
VBA Loop Until ignoring second condition
My RootCheck2 is designed to check if it is in fact a root or instead a vertical asymptote. It seems to be ignoring that second condition as the code is currently outputting both asymptotes and roots. The Oldx that the code outputs gives an fOldx greater than 5, leading me to believe that it's ignoring the second condition. Please let me know if I'm missing anything, thank you Public Function SearchPsi(ByVal Variables As Range, ByVal x As Double) As Double Dim Oldx As Double Dim Checkx As Double Dim fx As Double Dim fOldx As Double Dim fCheckx As Double Dim RootCheck1 As Boolean Dim RootCheck2 As Boolean Do Oldx = x x = Oldx + 0.1 Checkx = Oldx + 0.01 fx = PSI(Variables, x) fOldx = PSI(Variables, Oldx) fCheckx = PSI(Variables, Checkx) If (fx * fOldx) < 0 Then RootCheck1 = True End If If Abs(fOldx) < 5 Then RootCheck2 = True End If Loop Until RootCheck1 = True And RootCheck2 = True SearchPsi = Oldx End Function
Do Oldx = x x = Oldx + 0.1 Checkx = Oldx + 0.01 fx = PSI(Variables, x) fOldx = PSI(Variables, Oldx) fCheckx = PSI(Variables, Checkx) Loop Until (fx * fOldx) < 0 And Abs(fOldx) < 5
SymPy : Cancel out unnecessary variables and coefficients
I have an expression like : b = IndexedBase('b') k = IndexedBase('k') w = IndexedBase('w') r = IndexedBase('r') z = IndexedBase('z') i = symbols("i", cls=Idx) omega = symbols("omega", cls=Idx) e_p = (-k[i, omega]*r[i]/w[i] + k[i, omega]*r[i]/(b[omega]*w[i]))**b[omega]*k[i, omega]*r[i]/(-b[omega]*k[i, omega]*k[i, omega]**b[omega]*r[i]*z[omega]/w[i] + k[i, omega]*k[i, omega]**b[omega]*r[i]*z[omega]/w[i]) e_p = simplify(e_p) print(type(e_p)) print(e_p) <class 'sympy.core.mul.Mul'> -(-(b[omega] - 1)*k[i, omega]*r[i]/(b[omega]*w[i]))**b[omega]*k[i, omega]**(-b[omega])*w[i]/((b[omega] - 1)*z[omega]) So k[i, omega] should be canceled out when I use simplify() function but do nothing. How can I get rid of unnecessary variables and coefficients?
Javascript Append to Text File
I have several JavaScript files that when run return no errors, but do not do what is coded inside them. This is one of them. Is there something else I should have installed or enabled on the PC running the .JS files? function WriteDemo() { var fso, f, r; var ForReading = 1, ForWriting = 2; fso = CreateObject("Scripting.FileSystemObject"); f = fso.OpenTextFile("c:\\testfile.txt", ForWriting, true); f.Write("Hello world!"); f.Close(); f = fso.OpenTextFile("c:\\testfile.txt", ForReading); r = f.ReadLine(); return(r); }
According to the MSDN article on FileSystemObject, for JavaScript you should use new ActiveXObject instead of CreateObject (that's for VB). function WriteDemo() { var fso, f, r; var ForReading = 1, ForWriting = 2; fso = new ActiveXObject("Scripting.FileSystemObject"); f = fso.OpenTextFile("c:\\testfile.txt", ForWriting, true); f.Write("Hello world!"); f.Close(); f = fso.OpenTextFile("c:\\testfile.txt", ForReading); r = f.ReadLine(); return(r); } And, of course, don't forget to call the function. :) WriteDemo();
when a spawn object moves across the screen, I want it to despawn once it gets to a certain x value?
I have random spawned objects that automatically moves across the screen. I want it so that when the objects reach a certain x position it despawns itself. local mRandom = math.random local objects = {"Vehicle11" ,"Vehicle21","Vehicle31","Vehicle41"} local objectTag = 0 local object = {} local function spawncarright() local rightcar = {408,312} objectTag = objectTag + 1 local objIdx = mRandom(#objects) local objName = objects[objIdx] object[objectTag] = display.newImage(objName..".png") -- see the difference here object[objectTag].x = 32 object[objectTag].y = rightcar[math.random(1,2)] object[objectTag].name = objectTag transition.to(object[objectTag], {time = 3500, x = 348}) end timer.performWithDelay(2000,spawncarright,0) so once reaches object[objectTag].x = 348 the object despawn
Try this: local function deSpawn() for i=1,objectTag do if(object[i]~=nil and object[i].x~=nil and object[i].x>=348)then -- If you want to remove the object, then use the following 2 lines -- object[i]:removeSelf() print("Removed object["..i.."]") --or else if you want to reposition the object, then uncomment the following -- --[[ spawncarright() --]] end end end Runtime:addEventListener("enterFrame",deSpawn) Keep coding................... :)
You should do it within the transition.to call: object[objectTag].deleteSelf = function(self) object[self.name] = nil -- Remove reference to object in table display.remove(self) self = nil end local localObj = object[objectTag] -- Do this so the object doesn't change with the objectTag does; if objectTag is incremented, then when the transition ends, it won't be pointing to the same object when we call the function transition.to(localObj, {time = 3500, x = 348, onComplete = function() localObj:deleteSelf() end})