go to post Nikita Savchenko · Jun 14, 2016 OK :) But how to use this variable name generator? :) set myNewVarName = ..GetNewVarName() // oops, no set @..GetNewVarName() = "" // now it's OK, but I need to call this function once more set @..GetNewVarName() = $ORDER(@@..GetNewVarName()) // oops, another variable names Things get complicated here. I think we can stop on the solutions Michael and Timothy proposed. Thanks!
go to post Nikita Savchenko · Jun 14, 2016 Thank you, Timothy! This is good, but what if user specify ^||VariableNameList process-private variable before calling the method? The value will be lost: USER>set ^||VariableNameList = "TempVal" zwrite ##class(Test.Class).GetVariablesByTimothy() $lb("Einstein","Mozart") USER>write ^||VariableNameList ...TempVal is now gone!... Maybe there is no absolutely save method to get the variables list without touching/rewriting other variables or globals. I hope it is enough just to name temporary variables as no one suggests to name.
go to post Nikita Savchenko · Jun 14, 2016 This is awesome. It works! Wondering how many things COS has. But it also outputs variable x. I wrapped your code into the method, and that's what I got: ClassMethod GetVariables() As %List { set UndefinedSpecialList = $LB() set UndefinedSpecialInt = 0 set Undefined = "" set Undefined = $ORDER(@Undefined) while (Undefined '= "") { quit:($ORDER(@Undefined) = "UndefinedSpecialList") set $LIST(UndefinedSpecialList, $INCREMENT(UndefinedSpecialInt)) = Undefined set Undefined = $ORDER(@Undefined) } return UndefinedSpecialList } It works awesome until user specify variables named UndefinedSpecialList, UndefinedSpecialInt and Undefined. I suppose user won't ever name variables this way, of course, but the method which will consider this is the winner.
go to post Nikita Savchenko · Jun 14, 2016 Thank you Fabio! The problem with all of the methods in %ZEN.Auxiliary.jsonProvider is that it writes JSON string directly to the current device, not allowing to get the string itself. But nevertheless I did it by rewriting this method and creating a custom method, which returns a string instead of printing JSON to the device.
go to post Nikita Savchenko · Jun 7, 2016 Thank you, Jon, it's good to know all the ways how this can be implemented.
go to post Nikita Savchenko · Jun 7, 2016 OK! Edward, Dmitry, thank you. Will try the timeout approach.
go to post Nikita Savchenko · Jun 7, 2016 Thanks, Dmitry, this is very close to what can be true. But to use this I need to interrupt WaitMsg method and check if the global exists each... Second? The one idea I come up with is to set timeout for that: set st = $system.Event.WaitMsg(, 1) if $LG(st,1)=0 {/*check if the process is gone and wait again*/} else {/*handle message*/} but is this the best way to do it? Are there any sort of registering trigger or system "interrupt" for this?
go to post Nikita Savchenko · Jun 6, 2016 Thanks.Apparently I reached another question now. How to terminate child process if the parent process is gone? WaitMsg method in $system.Event class does not return when the parent process terminates.
go to post Nikita Savchenko · Jun 6, 2016 Jobbed process runs independently of parent process.Killing a parent does not kill its children.Oops. Thank you, it does not kill children process really.In my application two processes already use interprocess communication. Child process rely on $ZPARENT variable. Is it possible to change it? Or the only way is to use custom variable to hold the parent's process ID?
go to post Nikita Savchenko · Jun 3, 2016 Thanks for the tips! My use case is only to get the string, it doesn't matter printable or not.I also tested that this works with nested lists, so everything is OK now:USER>set l = $lb(1,2,$lb(3,4,5),6) USER>w $LISTGET($LISTGET(l, 3), 2)4USER>w $LISTGET($LISTGET(l, 3), 1)3USER>w $LISTGET($LISTGET(l, 3), 3)5USER>w $LISTGET(l, 4)
go to post Nikita Savchenko · Jun 3, 2016 Thanks John, the above terminal transcript is not correct showing what I wanted to show. I've fixed this.Why can't you understand the purpose of this?I can only transfer strings by some channel (f.e. interprocess communication). Now I need to send the array of strings (list, object, etc) from sender to receiver. To send this array, I must convert it to the string and then, after receiving, convert it back to array to read it's elements. How to do this in Caché 2013.*? The strings in array can contain any characters, so it is not possible to specify any delimiter character.Finally I got why the question is pretty confusing for you. Just imagine, I didn't know that $lb() returns the simple string. I didn't know that I can write this string to file, read it from file, and then apply $LISTGET function to it. I didn't know $LISTGET function takes string type. I thought that $LIST is something more than just a string.So the solution:set string = $LB(1,2,3,",",5)/* send this string anywhere */set element = $LISTGET(string, 4) // = ","
go to post Nikita Savchenko · Jun 3, 2016 [UPD fixed] Got you. Incredible! It seems that this is what I needed:USER>set string = $lb($C(1),$c(2),$c(3),",",$c(0))USER>w $a($LISTGET(a,1))1USER>w $a($LISTGET(a,2))2USER>w $a($LISTGET(a,3))3USER>w $LISTGET(a,4),USER>w $a($LISTGET(a,5))0Until the list values may contain any set of characters here this is the best solution, thank you, Jon!
go to post Nikita Savchenko · Jun 2, 2016 Don't understand what are $lts and $lfs. I need to convert this string back to the structure, so I can read it's elements. The delimiter needs to be escaped somehow.
go to post Nikita Savchenko · Jun 1, 2016 Thanks! But if I have possibility to avoid using this method - I'll use one :)
go to post Nikita Savchenko · Jun 1, 2016 Nice, but how to deserialize this string? Are there any built-in methods to do so?
go to post Nikita Savchenko · May 10, 2016 John, you are right, in general any temporary namespace change should be new'd, as Timothy mentioned.But both inside CreateProjection and RemoveProjection methods not changing the namespace back to the original one at the end of the methods doesn't have any side effects as I discovered.
go to post Nikita Savchenko · May 10, 2016 The general approach here is to use COS' write command to output any user-readable result. This result will be visible during and after class import for any of three cases described in the article (importing with Caché Studio, Management Portal and terminal).
go to post Nikita Savchenko · May 10, 2016 Thank you, Evgeny!Showing the logs has a lot of use cases, but the most common of the top of my head are:To notify user that no errors occurred during installation and to help track any errors if any happened;To show the user what happened and what was configured;And even to collect installations statistics and catch any unpredictable error logs during setup, as I do in my VisualEditor project.
go to post Nikita Savchenko · May 9, 2016 Daniel, Also, in many cases, when you compile a class, you only want to perform changes only once, not with every compilation.This can be easily held in the case of Projections. For example, by testing whether the compiled installer exists in the system, or, as I do in my project, by checking if the project's global exists, whatever. The only thing you need to write all of this pure COS code to perform the checks and build the whole installation logic.Not sure if %Installer gives more control, except of the moment when you trigger the installation process. It looks for me as a kind of framework with a lot of useful things.The ideal variant here would be to trigger %Installer's setup from CreateProjection method I think.