go to post Rubens Silva · Aug 2, 2017 Indeed, those redirection routines aren't called anywhere. But they're redefined extensively around the Caché Class API.As you said it's cryptic and powerful enough to dictate the buffer workflow even though you don't use it explicitly.From my experiments, what I notice is:wstr handles every writewnl handles every !wchr handles every single charwtab handles tab usagewff handles every form feedAs used here.
go to post Rubens Silva · Aug 2, 2017 %Status always returned $$$OK and putting -3 instead -1 provided me the same feedback. The last line is still empty.Maybe it's something regarding the redirection routines. I can't really see that: wnl() do output($char(13,10)_$$$FormatText("Port (%1): ", hookName)) quitAs correct, since wnl doesn't even take a parameter where I could decide what to do.
go to post Rubens Silva · Aug 2, 2017 Updated to use %Stream.GlobalCharacter instead, thank you.Using eol also didn't resolved I guess. Here's the feedback: Port: Executing hook extension OnAfterSave from the class Port.HookTest ...Port (OnAfterSave): Port (OnAfterSave): First lineSecond linePort (OnAfterSave): Third linePort (OnAfterSave): Port: OnAfterSave returned without errors. ClassMethod OnAfterSave(sourceControl As %Studio.Extension.Base = "",InternalName,Location,Object) As %Status{ // ! skips the first line leaving it empty, actual message is pushed down to the second line. // should not even print it. write !, "First line" // First line is here, printed along with the second. write "Second line", ! // Third is still third line. But ! writes another empty line. write "Third line", ! return $$$OK}As you suggested, I changed it to use eol: if $isobject(content) { do content.OutputToDevice() do content.MoveTo(content.Size - 1) do content.ReadLine(, sc, .isEOL) } if 'isEOL write !
go to post Rubens Silva · Aug 2, 2017 It seems they have changed it to an image for newer releases. (Even Caché is now an image instead of pure CSS).Well, I do agree with crediting IS, however it should be something like:"Powered by InterSystems ENSEMBLE" like a single message, since the focus is to demonstrate your work, not theirs.
go to post Rubens Silva · Aug 1, 2017 Yeah, you can't upload photos directly to this forum and it is somewhat bad, even though there's a lot of image related configs that most won't even think about using... The only way is hosting in the cloud.
go to post Rubens Silva · Jul 31, 2017 Such a roundtrip for knowing something that should be configurable.I don't think you should depend on INetInfo since normally you know where you're hosting your service. Make the address configurable and this will prevent headaches, after that you just need to concatenate with your CSP file address.
go to post Rubens Silva · Jul 28, 2017 set number = "1234"write number?.N // 1, so it's integer.set number = "44.2d3"write number?.N // 0, so it's float, double or whatever data type with precison.You can read more about Pattern Matching here.
go to post Rubens Silva · Jul 28, 2017 Since no one answered that yet, maybe there isn't a known way of doing it.If that's really the case, I suggest you to create your procedure.This could work as the following: 1 - Routine B watches a global generated from Routine A using a scheduled task.2 - Process A triggers an exception.3 - Exception on routine A executes subroutine or method to that uses $stack to capture execution data.4 - Routine A stores data into a global and quits abnormally.5 - Routine B watches for new entries in the global, marks it as used/processed.
go to post Rubens Silva · Jul 28, 2017 I agree with @Amir Samary. Even though by using inheritance you're allowed to use method generators, it's still against against the SIngle Responsibility Principle, since the code is binding directly to the persistence (which it's SRP should be to work as a storage representation).Binding another responsibility to it could mean that sometime in the future the persistence would need to be rewritten to match the newer requirements, thus risking to break current applications and elevating technical debt.So my golden rule is: unless you're 120% sure that the result generated by the binded class won't change, or you're 120% sure that it still submits to the SRP, only then you can "adapt" the persistent class.But before that, I would recommend (priority order):1 - Use an utility method that takes the binding class name and returns the JSON or vice-versa. Can take an optional configuration object or flags to overwrite and determine the serialization behavior for the current case. 2 - Create a mirror class that extends exclusively from the Adapter. This keeps the persistent class clean and still allows it to be serialized.Also, there's a method for doing what I suggest on 1, I think it's been discussed here already.
go to post Rubens Silva · Jul 27, 2017 I think that the default convention for REST usage has been exploited too much already, to the point that most would prefer to have an extra feature than follow it strictly. Even Google and Facebook do it: though they use REST most of their services, they also allow to pass query parameters.I think it's due to their performance or readability policies.EDIT:By allowing query parameters, you can also prevent another rule break: Let's say I need to pass a lot of parameters to FETCH data from a resource. As REST demand, you need to use GET verb to fetch data from the resource if you won't change it.However if you can't use query parameters, you need to use POST or PUT to provide the payload (that modifies data) and this would break the CRUD rule as well.This is where I would balance the rule breaks, that is, I can't really disregard breaking a rule that actually prevents me from breaking another that's even more explicit.
go to post Rubens Silva · Jul 27, 2017 Yeah, I read that a few days ago. But I noticed it doesn't mention how to handle "?".Hmm, I see... so according to your idea, I basically have to fetch the parameters by using %request.Get.
go to post Rubens Silva · Jul 24, 2017 You're right, %Dictionary.CompiledClass actually overwrites the current %Persistent implementation for %Exists (which is called by %ExistsId).
go to post Rubens Silva · Jul 24, 2017 Because 2 years ago Caché Node JS hadn't an API supporting objects.
go to post Rubens Silva · Jul 24, 2017 That is because the CLS Package is used internally.InterSystems uses it to verify if the method is defined or not without throwing exception.This is probably faster than %ExistsId, because %ExistsId tries to open the instance beforehand instead.
go to post Rubens Silva · Jul 24, 2017 Though it works, it's not literal: another programmer could ask himself why you tested the method %New, thus requiring to add a comment for explaining it. However if you use ExistsId, you're literally saying about testing if the class exists.I know, it's just a detail, but still contributes for clean code directives.