• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Listing the names contained in a record
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Listing the names contained in a record


  • Subject: Re: Listing the names contained in a record
  • From: has <email@hidden>
  • Date: Wed, 30 Oct 2002 20:41:23 +0000

Hey,

[Note: I already replied to this qu. on the AS-S list where it first
appeared, recommending the OP replace their records with something more
appropriate if they can, eg:
<http://www.barple.pwp.blueyonder.co.uk/libraries/index.html#associativeArrayLib
>

If that's not possible, e.g. working with the tag-attribute records
generated by XML Tools, then EVIL HACK time it is. I've reworked an
algorithm I wrote for hashLib, and it's now fast enough to be usable
(though still not trustworthy). As it's a stinky, barely-tested hack, I'll
make _no_ guarantees it'll work correctly with other data and systems. But
if you're truly snookered, it may be better than nothing...]

--

Emmanuel wrote:

>RecordAccess OSAX is the way to go if you are not under OSX.

Yup, best option if you _can't_ avoid using records.


>Otherwise, if you work with Smile, one of the hairy hacks Andy is
>mentioning consists mostly in using Smile's "display" command to make
>the record into text, parsing the resulting string, and using "do
>script" (or "run script") to retrieve the value of a given property.
[...]
>set ps to text 2 thru ((offset of ":" in s)-1) in s --> "myprop"

That's okay if it only handles one property, and the identifier isn't
contained within pipes (eg: |FOO|, |x:y|). Otherwise, you need Heavier
Guns. Anyway, here goes nothing...

has (diving for the nearest bunker)

======================================================================

script _coerceToStringModule
on _getCDTSOffsets()
try
{a:0} as boolean --[hacky trick]
error "a record-to-boolean coercion is present." number 100
on error eMsg number -1700
end try
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "{a:0}"
set textFrom to (eMsg's first text item's length) + 4
set textTo to -(eMsg's second text item's length) - 2
set AppleScript's text item delimiters to oldTID
return {textFrom, textTo}
end _getCDTSOffsets

on coerceToString(theData)
try
set {textFrom, textTo} to _getCDTSOffsets()
try
{a:theData} as boolean --[hacky trick]
error "a record-to-boolean coercion is present." number
[NO-BREAK]100
on error eMsg number -1700
return eMsg's text textFrom thru textTo
end try
on error eMsg number eNum
error "Couldn't coerce to string: " & eMsg number eNum
end try
end coerceToString
end script

on _valueAsString(val)
if {val's class} is in {boolean, integer, real} then
return (val as string)
else if {val's class} is in {string, Unicode text} then
return ("\"" & val & "\"")
else -- anything else gets the full stringify treatment
return (_coerceToStringModule's coerceToString(val))
end if
end _valueAsString

-------

on _getFirstOffset(theString, findString) -- (faster than Standard
[NO-BREAK]Addition's offset)
try
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to findString
count of theString's first text item
if result is theString's length then
set theOffset to 0
else
set theOffset to result + 1
end if
set AppleScript's text item delimiters to oldTID
return theOffset
on error eMsg number eNum
error "Can't get offset: " & eMsg number eNum
end try
end _getFirstOffset

on _parseBarDelimitedKeyString(str)
set str to str's text 2 thru -1
set endOfKey to false
set theKey to ""
repeat until endOfKey
set char to str's first character
if char is "\\" then
set theKey to theKey & str's second character
set str to str's text 3 thru -1
else if char is "|" then
set endOfKey to true
else
set theKey to theKey & char
set str to str's text 2 thru -1
end if
end repeat
return theKey
end _parseBarDelimitedKeyString

-------
--PUBLIC

on extractRecordKeys(theRecord)
if theRecord's class is not record then error "Not a record."
[NO-BREAK]number 200
(*Notes on next line:
- 3-chars padding to prevent error when trimming last
'property' substring from string [a bit hacky, but quicker
than doing the comma-space trim in an 'if propertyIndex is
less than count of valueLengths' block]
- cTS() claims to return a string (unkown if this means ASCII
string or international text); value returned chokes
Standard Additions' offset command unless explicitly
coerced to int. text beforehand. I've no idea why (anyone?). In
any case, TID-based getFirstOffset() seems to give a worthwhile
speed improvement, so probably best just to keep using that.
*)
set propertiesString to (text 2 thru -2 of _coerceToStringModule's
[NO-BREAK]coerceToString(theRecord)) & " "
set keyList to {}
set valueList to theRecord as list
repeat with valRef in valueList
set valueLength to count of _valueAsString(valRef's contents)
if propertiesString's first character is "|" then
set theKey to _parseBarDelimitedKeyString(propertiesString)
set endOfKeyOffset to (1 + (count of theKey) + 1)
set keyList's end to theKey
else
set endOfKeyOffset to _getFirstOffset(propertiesString, ":")
[NO-BREAK]- 1
set keyList's end to text 1 thru endOfKeyOffset of
[NO-BREAK]propertiesString
end if
set propertiesString to propertiesString's text (endOfKeyOffset
[NO-BREAK]+ 2 + valueLength + 2) thru -1
end repeat
return keyList
end extractRecordKeys

-------
--TEST

tell application "Finder" to get item 1 of startup disk
set theRecord to {foo:"bar", c:result, bar:4.53453E-7,
[NO-BREAK]|ba-z|:{wibble:1}, |foo:\\\\ \|bar|:false, fff:date
[NO-BREAK]"Tuesday, October 1, 2002 12:00:00am", |month|:March,
[NO-BREAK]|class|:class}
extractRecordKeys(theRecord)
--> {"foo", "c", "bar", "ba-z", "foo:\\\\ |bar", "e, fff", "month",
[NO-BREAK]"class"}

======================================================================

p.s. You can avoid using the hacky coerceToString module if Smile's trusty
'display' command is available. (Hat-tip to Emmanuel.) Replace the
_valueAsString() handler with something like:

on _valueAsString(val)
tell app "Smile" to return (display val)
end _valueAsString

and you might yet get out of the place alive. Good luck. ;)

--
http://www.barple.pwp.blueyonder.co.uk -- The Little Page of AppleScripts
_______________________________________________
applescript-users mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/applescript-users
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: Re: Copying icons in OS X?
  • Next by Date: Re: File name search & replace question
  • Previous by thread: Re: Listing the names contained in a record
  • Next by thread: Re: Jeez, I must be very stupid... (Filtering a list of items...)
  • Index(es):
    • Date
    • Thread