Before we get too deep into Refs, I'd like to repeat what's said in the
Nisus Writer Macro Reference:
Generally you do not need to use Ref objects. They are mostly useful only when your macro is running slowly because it’s unnecessarily copying arrays or hashes, or when dealing with nested data structures.
That's for the benefit of anyone else reading this discussion, as generally you don't need to use or know about Refs when writing macros.
Presumably NWP text objects are immutables, and an array is (something like) a linked list. So every change to a text object really does create a brand new object and the linked list is just updated to have its (in this case 4th) item point to the new object
That's functionally correct at least as far as the array is concerned (though arrays aren't necessarily implemented as linked lists). Your array assignment statement ($grid[3] = "25") is merely changing the array itself. Your code doesn't access or modify the Ref you created.
Here's an example that helps show the difference between using a Ref and not:
Code: Select all
$text = "hello"
$modified = $text # the text is copied
$modified.append("!")
Prompt $text, $modified # "hello" and "hello!"
$text = "hello"
$modified = Ref.new($text) # use Ref to prevent copy
$modified.value.append("!")
Prompt $text, $modified.value # "hello!" and "hello!"
The top part of the code actually uses two Text objects. A copy is implicitly made during the assignment of the $modified variable.
The bottom part of the code sidesteps the copy by wrapping the Text object in a Ref.
That example is of course very contrived. You're more likely to use Refs if you need to pass objects around to custom commands (user defined functions). The macro reference goes into some detail describing why you might want to use Refs to wrap hashes or arrays, so they aren't copied as you pass them around between functions.
Text objects are also somewhat special in that they inherently sometimes use value semantics and other times use reference semantics. This is described in the macro reference's Text object documentation under "Storage Semantics". This is potentially confusing when trying to understand the inner workings of macros, but generally behaves correctly when you consider how text objects can originate differently. Some text objects are unique and it's less likely that you want to copy them and thus should use reference semantics (eg: a document's main text object), while other text objects are anonymous and ephemeral like the example string "hello" and thus should generally be copied.
Text objects that already use reference semantics don't need to be wrapped in a Ref. For those text objects you actually have the opposite problem: you might need to force an explicit copy if you don't want to modify the original text, eg:
Code: Select all
$doc = Document.active
$text = $doc.text
$independent = $text.copy
$independent.append("!") # does not modify the document's text
I hope this helps clarify the use of Ref at least a little bit. Please let me know if you have any more questions.