Sunday, November 27, 2022

#1 2021-03-25 03:36:19 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 1083

Simple example showing how to debug ASObjC

Simple example showing how to debug ASObjC script with
   class(), className(), superclass(), isKindOfClass and isMemberOfClass

Everyday AppleScriptObjC by Shane Stanley talk more about this in this book.

If your return is ocid type of message you could do this:

Applescript:

log (theString's superclass())'s |description|() as text

Applescript:

set theString to current application's NSString's stringWithString:"1AB123"
log theString's |class|() as list
log (theString's |class|())'s |description|() as text
log theString's className() as text
log theString's superclass() as list
log (theString's superclass())'s |description|() as text
log (theString's isKindOfClass:(current application's NSString))
log (theString's isMemberOfClass:(current application's NSTaggedPointerString))

set theString to current application's NSString's stringWithString:"1, A, B, 123"
log theString's |class|() as list
log (theString's |class|())'s |description|() as text
log theString's className() as text
log theString's superclass() as list
log (theString's superclass())'s |description|() as text
log (theString's isKindOfClass:(current application's NSString))
log (theString's isMemberOfClass:(current application's __NSCFString))

set anArray to current application's NSArray's arrayWithArray:{1, "A", "B", 123}
log anArray's |class|() as list
log (anArray's |class|())'s |description|() as text
log anArray's className() as text
log anArray's superclass() as list
log (anArray's superclass())'s |description|() as text
log (anArray's isKindOfClass:(current application's NSArray))
log (anArray's isMemberOfClass:(current application's __NSArrayI))

set theRecord to {a:1, b:"A", c:"B", d:123}
set theDict to current application's NSDictionary's dictionaryWithDictionary:theRecord
log theDict's |class|() as list
log (theDict's |class|())'s |description|() as text
log theDict's className() as text
log theDict's superclass() as list
log (theDict's superclass())'s |description|() as text
log (theDict's isKindOfClass:(current application's NSDictionary))
log (theDict's isMemberOfClass:(current application's __NSFrozenDictionaryM))

We could also use isSubclassOfClass

Applescript:

log ((theString's |class|())'s isSubclassOfClass:(current application's NSString))

We could do something like this in dictionary

Applescript:

set theDict to current application's NSMutableDictionary's dictionary()
log theDict's superclass() as list
log (theDict's superclass())'s |description|() as text

theDict's setObject:123 forKey:"key1"
log (key1 of theDict)'s superclass() as list
log ((key1 of theDict)'s superclass())'s |description|() as text

set theResult to theDict's objectForKey:"key1"
log theResult's superclass() as list
log (theResult's superclass())'s |description|() as text

theDict's setObject:"ABC" forKey:"key2"
log (key2 of theDict)'s superclass() as list
log ((key2 of theDict)'s superclass())'s |description|() as text

set theResult to theDict's objectForKey:"key2"
log theResult's superclass() as list
log (theResult's superclass())'s |description|() as text

theDict's setObject:{"A", "123", current date, "Some words", 123} forKey:"key3"
log (key3 of theDict)'s superclass() as list
log ((key3 of theDict)'s superclass())'s |description|() as text
log (key3 of theDict)'s firstObject()'s superclass() as list
log ((key3 of theDict)'s firstObject()'s superclass())'s |description|() as text
log (key3 of theDict)'s lastObject()'s superclass() as list
log ((key3 of theDict)'s lastObject()'s superclass())'s |description|() as text
log ((key3 of theDict)'s objectAtIndex:2)'s superclass() as list
log (((key3 of theDict)'s objectAtIndex:2)'s superclass())'s |description|() as text

set theResult to theDict's objectForKey:"key3"
log theResult's superclass() as list
log (theResult's superclass())'s |description|() as text

theDict's setObject:(current date) forKey:"key4"
log (key4 of theDict)'s superclass() as list
log ((key4 of theDict)'s superclass())'s |description|() as text

set theResult to theDict's objectForKey:"key4"
log theResult's superclass() as list
log (theResult's superclass)'s |description|() as text

return theDict as record

We could do something like this to output a dictionary to text

Applescript:

log theDict's |description|() as text

Or we could do something like this

Applescript:

log (theDict's descriptionInStringsFileFormat()) as text

We could also build a new dictionary from key array and ask for class.

Applescript:

set keyArray to current application's NSArray's arrayWithArray:{"key1", "key2"}
log (theDict's dictionaryWithValuesForKeys:keyArray)
log (theDict's dictionaryWithValuesForKeys:keyArray)'s |description|() as text
set theRecord to (theDict's dictionaryWithValuesForKeys:keyArray)
log "AppleScriptObjC Class: " & (theRecord's objectForKey:"key1")'s superclass()'s |description|() as text
log "AppleScriptObjC Class: " & (theRecord's objectForKey:"key2")'s superclass()'s |description|() as text
log "AppleScriptObjC Class: " & ((theDict's dictionaryWithValuesForKeys:keyArray)'s superclass())'s |description|() as text
set myRecord to (theDict's dictionaryWithValuesForKeys:keyArray) as record
log "AppleScript Class: " & class of key1 of myRecord
log "AppleScript Class: " & class of key2 of myRecord

We could also use display dialog to give information, here is example.

Applescript:

set theRecord to {firstName:"abc", lastName:"def"}
set theDict to current application's NSDictionary's dictionaryWithDictionary:theRecord
set theKeys to theDict's allKeys()
set theValues to theDict's allValues()
display dialog ("(" & (theKeys's superclass())'s |description|()) & ") " & theKeys's |description|()
display dialog ("(" & (theValues's superclass())'s |description|()) & ") " & theValues's |description|()
display dialog ("(" & (theDict's superclass())'s |description|()) & ") " & (theDict's dictionaryWithValuesForKeys:theKeys)'s |description|()

Ps. As you could see we do not need to convert ASObjC object to AppleScript object with
display dialog. The reason is the text string begins with "(" AppleScript text object. So the
rest will do it automatic.

We could also use Console.app:
We could also use Console.app with current application's NSLog("%@",<YOUR_VARIABLE_TO_LOG>)
If we are running Script Editor we could in Console.app search field type:
process:Script Editor and library:libffi.dylib (ps you have to type this seperate in search field)
Now you could save the search tag. Now you do not need to type |description|() as text
You could instead use current application's NSlog("%@",<YOUR_VARIABLE_TO_LOG>).

Last edited by Fredrik71 (2021-06-20 03:28:09 am)


Node-RED makes it easy to automate IoT

Offline

 

#2 2021-06-21 12:20:20 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 1083

Re: Simple example showing how to debug ASObjC

The log command could also give hints of problems their variable are not declared accessible globally.

Applescript:

use framework "Foundation"
use framework "AppKit"
use scripting additions

set theString to "Hello World!"
set theAttributedString to current application's NSMutableAttributedString's alloc()'s initWithString:(current application's NSString's stringWithString:theString)

set theString to my attributedStringWithAttributeName:(current application's NSFontAttributeName) setValue:(current application's NSFont's fontWithName:"Zapfino" |size|:17.0) inRange:{0, 1} attributedString:theAttributedString
-- log theString's |description|() as text

on attributedStringWithAttributeName:attributeName setValue:anValue inRange:anRange attributedString:attributedString
   attributedString's addAttribute:attributeName value:anValue range:anRange
   -- return attributedString
end attributedStringWithAttributeName:setValue:inRange:attributedString:

The code above do not return anything of a problem. But if we log the variable name theString
we will return a error: error "The variable theString is not defined." number -2753 from "theString"

We know we have set some values to the variable name theString, so why does it return error.

The reason is we forgot to set a return statement in a handler and in return we got a handler that was not declared as accessible globally. If you log inside the handler of attributedString you will see it return some values.

So here is the correct code.

Applescript:

use framework "Foundation"
use framework "AppKit"
use scripting additions

set theString to "Hello World!"
set theAttributedString to current application's NSMutableAttributedString's alloc()'s initWithString:(current application's NSString's stringWithString:theString)

set theString to my attributedStringWithAttributeName:(current application's NSFontAttributeName) setValue:(current application's NSFont's fontWithName:"Zapfino" |size|:17.0) inRange:{0, 1} attributedString:theAttributedString

on attributedStringWithAttributeName:attributeName setValue:anValue inRange:anRange attributedString:attributedString
   attributedString's addAttribute:attributeName value:anValue range:anRange
   return attributedString
end attributedStringWithAttributeName:setValue:inRange:attributedString:

Last edited by Fredrik71 (2021-06-21 12:28:25 am)


Node-RED makes it easy to automate IoT

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)