Re: Listing the names contained in a record
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.