Adrian - are you writing your own Perforce hooks or use the sample Perforce hooks that ship with Caché? (%Studio.SourceControl.ISC.cls).

In %Studio.SourceControl.ISC.cls it checks to see if the file in the local workspace is Readonly or ReadWrite.  If Readonly it assumes it is not checked out and prompts the user to check out.  If ReadWrite it will see if it is a multi-developer or single-developer instance.  if single developer it can just edit it.  If multi-developer it will check in %Studio.SourceControl.Change to see if the current user is the one who checked it out - if so they can edit, if not they can a message of who is editing it in the Output window and the item is treated as ReadOnly to them.

Alex - I think it isn't a smart idea to call into a specific line number of a routine since the contents will change.  Instead you should call the line labels/functions called within the routine by outside of the routine and pass all appropriate variables, etc that way.

Trying to call a specific line number will certainly lead to faster than desired 'bit rot' in your unit test library.

Make sure that you review all of the shortcuts outlined in the documentation (there are a LOT of useful ones there):

Also, check out one of my favorite things to do with Studio which isn't as widely known as it should be:

Hope that helps :)


You can use $version(1) to see if it is Windows (returns '2') or UNIX (returns '3').  If you want to get really fancy you can include and then use the $$$isUNIX and $$$isWINDOWS calls (which just check to see if $version(1) is 2 or 3).

Personally, I like using ##class(%Studio.SourceControl.ISC).RunCmd() as it wraps the capture of the output for parsing.

You can tie $version together the other answers into something that is platform independent (warning, I haven't tested this, but I believe the pieces work):

If ($version(1)=2) {

   //Is Windows

   set sc=##class(%Studio.SourceControl.ISC).RunCmd("Ver",.out,0)

   set OS = out(1)

   // exercise of parsing exact desired version piece from the string is an exercise left to the reader

} elseif ($version(1)=3) {

   //Is UNIX

   set sc=##class(%Studio.SourceControl.ISC).RunCmd("uname -a",.out,0)

   set OS = out(1)

   // exercise of parsing exact desired version piece from the string is an exercise left to the reader

Hope that helps you Paul!


You are absolutely correct that using Client-Side source control hooks (ie the Eclipse Git hooks with Atelier) in a Shared development instance is a recipe for disaster and frustration.  You options are moving to Private development environments (each developer gets their own Namespace, or instance, or VM or container), or move to Server-side source control hooks.

I did an in depth session on this at Global Summit 2017 which should be of interest to you.  You can watch the recording and get the slides here:



Eduard - I think Arcady was asking from a purely data-processing perspective.  I.e. if you are already have a bunch of in-memory data and need to process/iterate on it, is it better to stick it in traditional structures and use $Order, or is it equivalent to stick it into the new structures for iterating and processing?  I think it's a good question and I would also like to hear what people think :)