go to post Joel Solon · Aug 23, 2018 Hi Timur! Your short answer is funny, and your longer answer makes sense (even though my preferences are different).
go to post Joel Solon · Aug 23, 2018 This is nice. The only thing I'm wondering about is why there are #dim statements for regular variables? @Timur.Safin, why did you include the #dim statements? In my opinion, #dim statements for variables that are not object references are misleading:#dim gives developers that are new to ObjectScript the impression that you must declare all variables like in some other languages. Declaring variables like this is not necessary in ObjectScript.#dim's main purpose is to help Atelier/Studio provide code completion for variables that are object references. If you write this code #dim i as %Integer, and then on the next line you type do i. , after the period Atelier/Studio will suggest methods from the %Integer class. If you happen to accept one of the suggestions, the resulting code will not compile. This is because our datatype classes (like %String and %Integer) are not object classes.
go to post Joel Solon · Aug 23, 2018 Yes, Track Variables in Studio is great! But I don't see any value in Option Explicit, which forces #dim, which leads to the issues in my original comment.
go to post Joel Solon · Feb 5, 2018 Both running VMs and containers allow multiple processes inside. I'm not asking you for a deep dive, but can you explain if the mechanism that allows this is the same or similar between VMs and containers, or if they use completely different mechanisms.
go to post Joel Solon · Jan 31, 2018 I would do it this way to avoid Else:Open <some device>:"R":0 If '$test { Write "could not open device" Quit }
go to post Joel Solon · Jan 31, 2018 Danny and Robert, of course I understand what you are saying (we are the same generation!). Also, I am not trying to be the Developer Community police.In posts that are asking "what's the recommended way to do this?" we should answer that question. There's no point in mentioning old syntax in that context. Saying "don't do this, but you might see it someday" helps the subset of people that might work with old code, but doesn't help and may confuse the people that are working with new code. It doesn't belong.On the other hand, if there's a post asking "what are some older/confusing syntaxes I might encounter when working with M or ObjectScript?" we should answer that question. We all have examples of that.
go to post Joel Solon · Jan 31, 2018 C'mon, let's stop mentioning old features like argumentless Do and legacy ELSEThere's just no point in doing so.
go to post Joel Solon · Jan 31, 2018 The legacy versions of If and For commands don't use curly braces. But there are no legacy versions of While and Do/While, which require curly braces. So rather than trying to remember which commands use or don't use curly braces, just use curly braces all the time for these, as well as Try/Catch.Regarding post-conditionals, it's a good habit to put parentheses around the condition, which allows you to put spaces in the condition.This is valid syntax: set:a=4 y=10This is valid syntax and more readable: set:(a = 4) y = 10This is invalid syntax: set:a = 4 y = 10
go to post Joel Solon · Nov 3, 2017 Slightly improved syntax would be something like this:if ($zdh(date1,8)<$zdh(value,8)) && ($zdh(value,8)<$zdh(date2,8)) { return 1 } else { return 0 }
go to post Joel Solon · Nov 1, 2017 Setting Startup Namespace in the User definition affects Terminal logins. The feature was expanded to affect the Portal in v2014.1
go to post Joel Solon · Nov 1, 2017 No. I have a feeling that some versions of M that ran on VMS added the $, and some versions of M that ran on UNIX added the !. So we support both.
go to post Joel Solon · Oct 16, 2017 And don't forget about using ! or $ to load the interactive sub-shell.load interactive subshellIt's like using $zf(-1). You can do !pwd or $dir, for example.
go to post Joel Solon · Apr 15, 2017 I haven't seen this crash at all. Is it possible to share more details about the crash? Error message, for example. Also, if the last edited routine is locked, that doesn't require a restart of Caché. You can find the entry for the routine in the Lock Table (in System Operations) and delete it.
go to post Joel Solon · Mar 29, 2017 Regarding the user for Caché/Ensemble processes, the user for those is not always the user that starts/stops Caché/Ensemble. My instance of Ensemble runs on the Mac. For several years, I do a custom install so that I can change the answer to the 4th question below from cacheusr to joelsolon.User who owns instance: joelsolonGroup allowed to start and stop instance: staffEffective group for Ensemble processes: cacheusrEffective user for Ensemble SuperServer: joelsolonAll the Ensemble processes run as OS user joelsolon because of this.I don't actually have an answer to your question, but maybe these points will help.
go to post Joel Solon · Mar 29, 2017 One clarification that might help you: the "Ensemble Controller" Service is not an Ensemble process, so the user assigned to that Service doesn't affect what you're asking about. The "Caché/Ensemble Controller" Service is simply something that allows you to start/stop the local Caché or Ensemble. It's just like start/stop on the Launcher (the cube or the E).
go to post Joel Solon · Mar 28, 2017 It is possible to programmatically add a relationship to two persistent class definitions at runtime, and then compile those classes. That gives you the same result you'd get if you had added the relationship to the class definitions at design time. So I don't think that's what you want.The term "Relationship" as defined in Caché means "objects of these classes can be linked at runtime, and this relationship will be stored when the objects are saved." So your need to create relationships between persistent objects "as and when they're required" doesn't really match up with this definition. Either a persistent class is in a relationship with another persistent class, or it isn't. It's not possible to have some objects of the class without the relationship definition, and other objects of the class with the relationship definition.Maybe you just need to substitute one-many relationships for all of your parent-children relationships. One-many relationships are independent; the relationship is not required like it is in parent-children relationships. In v2013.1 and later, you can set the OnDelete action of the one-many relationship to "Cascade" so you get delete behavior similar to parent-children.
go to post Joel Solon · Dec 30, 2016 Files are now also here: https://github.com/joelsolon/DevCommunity/tree/master/AppMon
go to post Joel Solon · Dec 1, 2016 Here is some information about debugging CSP pages using Studio. I actually just taught this to students in class yesterday!1. You can't set a breakpoint inside the ObjectScript on a CSP page (inside a <script> tag). But the workaround for this is to use the View > View Other Code and load the class definition that's generated from the CSP page. Then you can set breakpoints normally.2. Once you've set breakpoints, you can set your CSP page as the Debugging Target, and launch it directly from Studio. The page runs in a special "debug mode". This means that the normal timeouts (typically 60 seconds) are suspended, so that the browser and the CSP Gateway will wait as long as necessary while you step through the code.You can step through the code that is called when the page is first being built, and you can also step through code that is called via a hyperevent.The only issue with stepping through the code is that Studio does not seem to be highlighting the current line as it normally does. I think this used to work fine, so I may bring this up with the developers. But a workaround for now is to use the "Call Stack" tab of the Watch Window. The top line of the call stack shows the label+offset of the current line. As you step, the top line is updated with the current label+offset. You can simply click the top line whenever you want and the Code Window will scroll to that line, also showing you the current values of the variables.