Ah, I misinterpreted "this alias" in your post! So you meant (I added italicized text): "I like to define :sql as a way to launch the shell and execute a statement - so that means this built-in :sql alias should be renamed by InterSystems to something else!! or be removed."

At least aliases defined in .iris_init override any built-in aliases.

Here's some info that was inadvertently removed from the docs, but will be returning soon:


On Unix systems, if a file named ~/.iris_init exists, it is read when a terminal session is initiated. Only lines starting with :<command> are processed. All other lines are ignored. This file accepts only :alias commands, which enables you to store favorite command abbreviations there.
Example of a ~/.iris_init file:

# Initial aliases
:alias %  zn "%SYS"
:alias load Do $System.OBJ.Load("$1",$S("$2"="":"ck",1:"$2"))
:alias ut Do ##class(%UnitTest.Manager).RunTest("$1")

Nice article about an important question: when should you touch the storage definition? Some comments on the scenarios (with sound effects!). The only modifications I'd make to the bookshelf analogy is that there are gazillions of shelves (every person gets their own shelf) using the mapping of what type of book goes in each slot.

  1. Scenario 1: You are creating a class, and adding, deleting, and renaming properties. If there's any data for the class, it is test/temporary data and can be deleted at will. As Vivian saw, deleting a property doesn't change the storage definition (the slot for the deleted property is left unused), and renaming a property is really a deletion (old slot unused) followed by an addition (new slot). Once you get the class the way you want it for release, you can safely delete the storage definition (since there's no real data) and the next compilation will create a fresh one, with no unused slots. No danger (cue happy music).
  2. Scenario 2: You are editing an existing class with real stored data. If you rename any property (new or existing, with or without data) it's best practice to rename the storage definition slot also before your next compile. If it's a newly added property without data and you don't bother to rename the slot, it's OK, but you now have a wasted slot that will never be used, and a new slot for the data you'll eventually start saving. Why not rename the slot right away? On the other hand, if it's a property that has data, you must rename the storage slot, or the data for that property will no longer be accessible, and new data for the renamed property will go in a different slot. Any danger is prevented by renaming the property and storage definition slot at the same time (cue triumphant marching music).
  3. Scenario 3: You delete a property with real stored data. As before, the old slot is left unused. Any new property added later will not use that slot (no double-booking; new data won't ever be added there). But the real question is: Why are you deleting the property? Do you not care about that data anymore? If so, why aren't you deleting the data first? And by deleting the data, I don't mean editing the global directly (which I think is what Vivian meant by "don't do this."). But it's not dangerous to the table to use SQL to delete Book B from every bookshelf before deleting the property:update schema.table set property = null(cue computer bleeps).

Editing the name of any unused slot in the storage definition and adding "-unused" to make things clear could be OK but it's definitely not intended for that use. I'm not sure it's necessary to do anything in this case; If I see a slot in the storage definition named XYZ and there's no property XYZ, I know it's an unused slot. Maybe preceding the storage definition with a comment section would be cleaner:

/* unused slots
   XYZ (as of 1/1/2020)
   ABC (as of 6/1/2021)
*/

Please let me know if it's not clear, or if I missed a scenario.

Very strange! I was never on the standards committee. I started using MUMPS in 1987, and I remember it differently ($next being replaced by $order). Let me check the archives...

  • My 1981 copy of the Standard MUMPS Pocket Guide states that variables can have only non-negative integer subscripts, and lists $next (returning -1 if no more subscripts exist), but there's no mention of $order.
  • My 1983 copy of the Pocket Guide (based on the 1977 ANSI Standard) states that variables can use any string as a subscript and lists $order (both noted as approved extensions of the Standard; $order using "" as both the seed and the flag for no more subscripts), and $next is still listed.
  • My 1987 copy of the Pocket Guide (based on the 1984 ANSI Standard) has the same info as the 1983 Guide, except the approved extensions are now part of the Standard.
  • My 1995 copy of the Pocket Guide (based on the 1995 ANSI Standard) lists the 2 argument form of $order, but $next (having been deprecated) is not listed.

Public viewing of the Solon Archives available by appointment only ;-)

https://www.youtube.com/watch?v=rIz_xhYK2Mo

All I can say is Wow! I experienced many of the same things over my career, but I was living in safe, protected, training-room-land, not the real world of development like Nigel. Great article!

I'll just note that Nigel says "might" in the title. laugh

One thing that confused me, Nigel. You wrote "If one of the early MUMPS creators had called $order "$next", it would immediately be recognizable as Next()...". But I know that you know that the original $order was called $next.

Hi Robert,

Why did you say that the %TimeStamp datatype is the equivalent of the full $h? It's true that %Date/%Time do the conversion from internal date/time values to/from external. But %TimeStamp, %DateTime, and %StringTimeStamp  do not do any internal/external conversion. It's just for the YYYY-MM-DD HH:MM:SS external timestamp. Is there something I'm missing?

%PosixTimeStamp does convert, but it's not $h internally.

I have been using VS Code with client-side editing exclusively. Now I'm playing with server-side editing, and I'm hoping that @John Murray or someone else can clear up my confusion about something. Before Server Manager had a GUI, my (possibly incorrect) understanding of server-side editing was that there were two ways to configure it:

  • The preferred way was to use the isfs "technique" as described in the documentation
  • Just click "Choose Server and Namespace" without creating a Workspace (no local folder)

It now appears that clicking "Choose Server and Namespace" automatically uses the isfs technique. Now I'm wondering:

  • Did the behavior of "Choose Server and Namespace" actually change? I'm kind of hoping that it didn't change, but if it did...
  • What's the difference (if any) between the two techniques for server-side editing, and is there any reason to still use the non-isfs approach, and if so, how would I configure that?

Also note, for the name of the global that is logging statuses:

  • ^mtempinitials works (since the old days), like  ^mtemptl in Tim's example above.
  • ^CacheTempinitials also works (since the Caché days). Maybe Tim would use ^CacheTempTL sometimes  and rock a little camelcase?
  • ^IRIS.Tempinitials also works (for IRIS). Maybe Tim would use ^IRIS.Temp.TL periodically? (see what I did there?)

Nice article Tim! For posterity, I will try to clarify two statements you made:

  1. "Note that this solution assumes uniform depth of subscripts/values across the whole local array; weird things would happen if this assumption was violated."
  2. "$query, $qlength, and $qsubscript are handy for dealing with globals/local arrays of arbitrary depth."

Some readers might see a conflict in these two statements (I added the bold), but there is no conflict. Statement #2 is correct. Statement #1 applies to using $query for the specific goal Tim had in mind.