b28: Pass by Reference

Need help with a script? This is the place to discuss how to get your code running!

b28: Pass by Reference

Postby sctell » Thu Jul 13, 2017 6:42 am

The following script when passed tArray seems to end up with the data corrupted.

add 0.00 to item 4 of tRec started to generate an error "Expected long integer but found something else".

On investigation item 4 of tRec was actually referencing item 2 of tRec which is text.

The function when used without @ performs as expected.

Must be a bug somewhere or I don't understand how to use @.

All the best

Terry


Code: Select all
function formatArrayData tArray
    put 1 into n
    set the itemDelimiter to tab
    put "0.00" into tBalance
    repeat for each line tRec in tArray
        set the numberFormat to "0.00"
        add 0.00 to item 4 of tRec
        add item 4 of tRec to tBalance
        put tBalance into item 5 of tRec
        convert item 1 of tRec to short date
        convert item 4 of tRec to currency
        convert item 5 of tRec to currency
        put tRec into line n of tArray
        add 1 to n
    end repeat
    return true
end formatArrayData
sctell
 
Posts: 1128
Joined: Sun Jul 06, 2008 10:41 am

Re: b28: Pass by Reference

Postby codegreen » Sun Jul 16, 2017 9:56 am

Must be a bug somewhere or I don't understand how to use @.

Actually the problem is likely that you're modifying tArray while you're walking through it with a for-each loop.

That's verboten...

-Mark
codegreen
 
Posts: 1504
Joined: Mon Jul 14, 2008 11:03 pm

Re: b28: Pass by Reference

Postby sctell » Sun Jul 16, 2017 11:17 am

codegreen wrote:Actually the problem is likely that you're modifying tArray while you're walking through it with a for-each loop.


Thanks for that info Mark. This should be put in the docs somewhere.

I assumed, incorrectly, that it was similar to passing a pointer in Objective-C

or

are you saying you cannot walk through tArray even if it has not been passed with @

or

is it just the "put" that is the issue because the "convert" lines work.

All the best

Terry
sctell
 
Posts: 1128
Joined: Sun Jul 06, 2008 10:41 am

Re: b28: Pass by Reference

Postby codegreen » Mon Jul 17, 2017 9:15 pm

Sorry for the delay, been crazy busy...

Unfortunately the problem isn't quite as simple as that. Variables are stored in a Hydra-headed data structure with multiple internal representations (the one that's used can vary over the life of the container as it's dynamically typed and shrunk/grown). When you walk a var with a for-each loop it's first converted to a Handle (if it wasn't one already) and then you walk the block of chars the Handle points to at the point when you enter the loop by advancing a pointer through it according to the rules of the applicable chunk.

Handles don't move in OS X, but (depending on runtime memory layout) if you grow one the block it indirectly points to may need to be reallocated somewhere else, which leaves the loop's 'walking' pointer dangling. So the outcome depends partly on what you're doing (i.e., whether it makes the walked variable grow longer) and partly on what's immediately after your variable's allocation in the heap when you try to enlarge it.

BTW FWIW you can often limit the effect of resizing on Handle-based variables by first making them at least as long as you expect them to ever grow then shrinking them, because modern iterations of the OS X memory manager allocator will leave the intervening space blank until things really get tight. The downside is that larger initial allocations can incur paging overhead (especially when memory is tight), so YMMV...

-Mark
codegreen
 
Posts: 1504
Joined: Mon Jul 14, 2008 11:03 pm


Return to Scripting in SuperTalk

Who is online

Users browsing this forum: No registered users and 1 guest