Monday, December 18, 2017

#1 2017-10-08 02:59:24 am

pwapub1
Member
Registered: 2017-08-22
Posts: 5

How to encapsulate and reach to an external handler

Hi reader,

The following AppleScript does not work. When run in "Script Debugger", it fails at the call to "addtwonumbers(x,y)" claiming that this entity is not understood - i.e., it can't be located/accessed.
Commenting out the line "property parent : AppleScript" allows it to work as expected.

The question is -
    if I use "property parent : AppleScript"
    how can I get the encapsulated handlers get to external handlers

The reason I want to use the the "property parent : AppleScript" is that if I do not - "LNS Script Debugger" states that there is an "internal table overflow", throws an error and will not allow me to debug the script in debug mode (the internal table overflow message does not occur when debug mode is switched off). The script itself is not that big - a hundred lines or so. The problem causing the internal table overflow error appears to be the result of several objects being defined and initialized.

Anyway - any suggestions how one might solve this problem would be much appreciated.

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on addtwonumbers(a as integer, b as integer)
   return (a + b)
end addtwonumbers

on encapsScript()
   script abc
       property parent : AppleScript
       property c : 0 as integer
       
       on testThis(x as integer, y as integer)
           set c to addtwonumbers(x, y)
           return (c)
       end testThis
   end script -- abc
end encapsScript

local d

set es to encapsScript()
tell es
   set d to testThis(1, 2)
end tell
d

Offline

 

#2 2017-10-08 05:50:09 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5200

Re: How to encapsulate and reach to an external handler

Two suggestions:

* Don't try to solve the problem by using a parent property like that. It's not the answer (as you have already found out).

* Don't try to treat AS handlers as objects; they're not, and even though they sometimes appear to behave as such, it is at best undefined bahavior. If you want an object, use a script object:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on addtwonumbers(a as integer, b as integer)
   return (a + b)
end addtwonumbers

   script abc
       property c : 0 as integer
       
       on testThis(x as integer, y as integer)
           set c to addtwonumbers(x, y)
           return (c)
       end testThis
   end script -- abc

local d

tell abc
   set d to testThis(1, 2)
end tell
d


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#3 2017-10-08 02:18:42 pm

pwapub1
Member
Registered: 2017-08-22
Posts: 5

Re: How to encapsulate and reach to an external handler

Hi Shane and other interested readers,

Thanks for the suggestions - intriguing! When I read AppleScript language references several suggested that by wrapping a "script" in a AS handler I could use the construct to create instances of a scrip object. This became  useful because I could then do something like in the code snippet below (which is using the construct like it was an object).

The result is effectively two objects that have different local storage states.

As you point out - this construct and usage creates problems that can be masked by using a parent property - but that has side effects as well. So better to avoid this method.

Is there a syntax that allows me to do what I want a script object (creating separate instances) without using an AS handler?
If not I will have to rethink how I use AppleScript.

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on addtwonumbers(a as integer, b as integer)
return (a + b)
end addtwonumbers

on encapsScript()
script abc
property parent : AppleScript
property c : 0 as integer

on testThis(x as integer, y as integer)
set c to addtwonumbers(x, y)
return (c)
end testThis
end script -- abc
end encapsScript

local d

set es1 to encapsScript()
tell es1
set d to testThis(1, 2)
end tell

set es2 to encapsScript()
tell es2
set e to testThis(4, 5)
end tell

Offline

 

#4 2017-10-08 04:04:43 pm

Marc Anthony
Member
From:: Dallas, TX
Registered: 2006-04-27
Posts: 772

Re: How to encapsulate and reach to an external handler

Hi. Perhaps I don't understand the question or goal, as I'm not really sure why an object is needed to have something be local. Things defined within a handler are local instances, unless explicitly made global; my example violates the handler's stated purpose of simply adding two numbers, but it demonstrates this point.

Applescript:


set c to 20
display dialog addTwoNumbers(1, 2) -->10, since local c was added to last handler operation
display dialog c -->20, since global c

#global c --if enabled, c will be set by the handler; in this case -->7



on addTwoNumbers(a, b)
   set c to 7
   (a + b) + c
end addTwoNumbers

Offline

 

#5 2017-10-08 05:52:13 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 5200

Re: How to encapsulate and reach to an external handler

pwapub1 wrote:

Is there a syntax that allows me to do what I want a script object (creating separate instances) without using an AS handler?



Your original code without the parent property is doing what you want. The handler is returning its last result, which is a script object. If you're getting internal table overflows, you need to try to work out why that's happening.

Having said that, my personal opinion is that although AppleScript is in theory an OOP language in this sense, using it as such is often unnecessary, and sometimes problematic.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/

Offline

 

#6 2017-10-09 07:59:58 am

DJ Bazzie Wazzie
Member
From:: the Netherlands
Registered: 2004-10-20
Posts: 2728
Website

Re: How to encapsulate and reach to an external handler

pwapub1 wrote:

Is there a syntax that allows me to do what I want a script object (creating separate instances) without using an AS handler?



There is another method like this:

Applescript:


script anClass
   property anValue : missing value
   
   on setValue(val)
       set my anValue to val
   end setValue
   
   on getValue()
       return my anValue
   end getValue
end script

copy anClass to instance1
copy anClass to instance2

instance1's setValue(1)
instance2's setValue(2)

return {instance1's getValue(), instance2's getValue()}

Basically the handler method and using copy are doing the same, they create an instance by copying an script object. There is however one major difference and that that the handler method is dynamic while the copy method is static. For example with the handler method you can send an parent property while that is not possible using copy.

Applescript:


on createInstance(_parent)
   script -- anonymous
       property parent : _parent
       
   end script
end createInstance

on add(a, b)
   return a + b
end add


set o to createInstance(me)
o's add(4, 5) -- Result: 9
set o to createInstance(AppleScript)
o's add(4, 5) -- Result: error

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)