ObjectScript

Syndicate content 29 

 

Cache tricks

Several years ago, long before Developer Community Portal was launched, I published a series of Caché tricks at one of Czech web sites. In this article, I’m posting translated version of one of them.

Capturing output of someone else’s methods or routines

Suppose you, or someone else created a useful method or routine, that was producing some computation that you’d like to benefit from, but the routine was writing output to process principal device.

You would like to use the data, but you need it not written to a device, but assigned to a variable. And, for any reason, you can’t modify the code. What can you do?

Last comment 26 July 2016
0 4
1324

views

+ 8

rating

              While Studio and Atelier are useful development interfaces, there are occasionally situations where a quick edit needs to be made to code and only terminal access is available.  A useful set of tools to do this are the zload, zprint, zinsert, zremove, and zsave commands.  These are abbreviated to zl, zp, zi, zr, and zs respectively.  While each of these commands has its own page in documentation, this article will synthesize that information with examples to provide instruction for their combined use.

Last comment 19 July 2016
0 3
366

views

+ 4

rating

I have the following problem:

  • There are several classes with method generators, which needs to be compiled during every compilation
  • I have "ckub" qualifiers enabled in studio
  • I don't want to remove "u" qualifier because I need it very much in another namespaces

So how do I force classes with method generators to recompile when "u" qualifier is present?

Last comment 15 July 2016
0 2
0

answers

495

views

0

rating

Hello, everyone!

I opened one project and there I found such lines as 

$$Export^%occXMLExport(filename,"-d /diffexport",InternalName)

Do DecomposeStatus^%apiOBJ(sc,,"d")

The problem is I can't go to their definition and find them in documentation. It says that they don't exist on the server. However, the project works and these routines execute. 

Last answer 12 July 2016 Last comment 14 July 2016
0 2
320

views

+ 1

rating

I've been trying to write a method to compare two local variables, which may be arrays, for "equality" - that is, to see if they have all the same subscripts (if they're arrays) and values. This is the best I've come up with so far - are there any better/simpler approaches out there

Last answer 11 July 2016
0 1
0

comments

618

views

+ 1

rating

Hello!

In Caché there is a way to print all current variables using write command without arguments:

USER>set Einstein = 1879
USER>set Mozart = 1756
USER>write
Einstein=1879
Mozart=1756

But is there a way to get a list of this variables? I am looking for something that would return value like $LB("Einstein", "Mozart") for this case.

Thanks!

Last answer 30 June 2016 Last comment 30 June 2016
0 1
826

views

+ 2

rating

Hi!

Here is the question in Russian Forum regarding roots extracting.

In Caché ObjectScript we use exponentiation operator (**) to raise an exponent to power. F.e. let's raise 3 to power of 3: 

USER> write 3**3 

27

And we use the same operator to extract the root. 

USER> write 27**(1/3) 

2.999999999999999963

And 2.999999999999999963 is not 3, obviously.

How to extract roots properly in Caché ObjectScript?

 

 

 

 

Last answer 24 June 2016 Last comment 28 June 2016
0 0
235

views

0

rating

I am testing application code and want to simulate error conditions. 

I am trying to use the following to define a custom error with a class method.

$SYSTEM.Status.Error($$$GeneralError,"Any text here")

My class method code looks like this....

set RunStatus=$System.Status.Error($$$GeneralError,"DXL Testing Run Error")

Class compile fails because the $$$GeneralError is unknown.

Last answer 23 June 2016 Last comment 23 June 2016
0 1
308

views

0

rating

Hi, Community!

Want to share with you one debugging approach from the Russian forum.

Suppose I want to debug the application  and I want it to stop the execution on a particular line.

I add in code this line:

l +d,-d

When I want to start debugging in this line I block d in terminal

USER> l +d

And execute the app.

The app stops on this line and lets me connect to it with Studio debugger.

To release lock I do in terminal

USER> l -d 

And what are your debugging practices?

 

Last comment 22 June 2016
0 5
297

views

0

rating

Hi,

I have a bit of code that does a find and replace on a "template" and inserts additional content. For example it replaces the @DATA@ with an html table:

<html>

   <body>

      <div id="data">@DATA@</div>

   </body>

</html>

Currently doing this with the $replace function:

Set text=$replace(text, "@DATA@", data)

The problem is the "data" is now too big for a %String (yes even with large strings) so will switch to use a stream instead. 

Is there an equivalent to $replace that works on a stream? If not, how would I best implement this sort of find/replace functionality in cache object script? Note: this is back end functionality that creating an html report that will be sent out via a soap webservice. It is not using zen.

thanks

Paul

 

 

Last answer 16 June 2016 Last comment 18 June 2016
0 1
575

views

0

rating

Hello,

I am still a beginner with COS and am struggling with these concepts. While digging through the official documentation will eventually tell you everything you need to know, getting started is nevertheless not an easy feat...

Is it possible to create a "lists/array/multidimensional 101" page for beginners? And, for instance, its interaction with $data, what it means to use "as list of something" or "as array of something", how to walk lists, how to add/remove elements, how to extract sublists etc?

At this moment, for me, this is all very confusing, and I think such a page would help me greatly in just, well, getting work done

Last answer 28 April 2016 Last comment 16 June 2016
0 2
254

views

+ 1

rating

Hello!

Are there any short ways of serializing COS entity to the string? I am searching for something like .$toJSON() , but I need Caché 2013.* support.

The one way I supposed to work is to use $listbuild:

 

set str = $LISTTOSTRING($LB(1,2,3,",",5))
set list = $LISTFROMSTRING(str,",")
zw list
list=$lb("1","2","3","","","5")

 

But the problem is that $listbuild does not escape delimiters, and it is not possible to deserialize serialized string. The structure I need to serialize may contain any characters.

Are there any short ways to do this in Caché to avoid writing custom parser?

Last answer 13 June 2016 Last comment 14 June 2016
0 3
1427

views

+ 1

rating

Order is a necessity for everyone, but not everyone understands it in the same way
(Fausto Cercignani)

Disclaimer: This article uses Russian language and Cyrillic alphabet as examples, but is relevant for anyone who uses Caché in a non-English locale.
Please note that this article refers mostly to NLS collations, which are different than SQL collations. SQL collations (such as SQLUPPER, SQLSTRING, EXACT which means no collation, TRUNCATE, etc.) are actual functions that are explicitly applied to some values, and whose results are sometimes explicitly stored in the global subscripts. When stored in subscripts, these values would naturally follow the NLS collation in effect (“SQL and NLS Collations”).

Last comment 10 June 2016
0 0
1540

views

+ 9

rating

We have noticed that when compiling with Atelier (either Atelier itself or sending the code through the REST interface) that the build will fail if all brackets '() {} []' are not closed. This includes brackets opened in comments.

 

For example, this will fail:

class myclass

{

//if someVar {

}

 

I do not know if this issue has been fixed or if this issue has been brought up, but it has been a nuisance over here.

Last answer 7 June 2016
0 1
0

comments

186

views

+ 1

rating

Hello!

I have a WebSocket application which spawns new process using JOB command.

Sometimes WebSocket connection can be terminated, and in the meantime I need to hold spawned process alive until it can be associated with the new WebSocket connection. (Do not suggest serializing process state here instead please)

Technically, in Caché WebSocket connection is represented by the class, which executes in its own process. This process is terminated when the connection is lost. In this case the JOBbed process does not terminates (thanks Edward), but it rely on $ZPARENT variable.

Is it possible to hold JOBbed process alive for a while? If yes, how to change $zparent variable of the spawned process when the new "parent" process will be ready?

Thank you.

Last answer 6 June 2016 Last comment 7 June 2016
0 2
169

views

0

rating

Hi, Community!

Last weekend we held the Final of InterSystems Contest on Caché, DeepSee and iKnow under the aegis of IT Planet Student Championship in Ekaterinburg. BTW, this year we had more than 1,400 participants in InterSystems Contest.

One of the tasks for the final was to solve T9 Spelling problem  with Caché ObjectScript and use the minimum code.

Last answer 1 June 2016 Last comment 6 June 2016
0 1
614

views

+ 3

rating

I am just trying to make a quick hand off HTTP production. I have the class built and compiled onto the server and the production is running as a service. When the production is called (by an inbound job) I can see that the HTTP.InboundAdapter is being used successfully and the stack continues all the up to ProcessInput where OnProcessInput is called in Ens.BusinessService. Instead of using the class that I wrote which has both extended Ens.BusinessService and implemented my own overriden OnProcessInput method, it calls the OnProcessInput within the Ens.BusinessService which just returns a $$$ERROR($$$NotImplemented).

The following is the output from the call

Last answer 25 May 2016 Last comment 1 June 2016
0 2
722

views

0

rating

NewBie's Corner Session 4 The Plus Sign and Concatenation Operators

Welcome to NewBie's Corner, a weekly or biweekly post covering basic Caché Material.

Click on the Caché Cube in your system tray and select Terminal to try out the commands.

Plus Sign (+) operator

Typically, the Plus sign (+) adds two numbers together. This is true in COS (Caché ObjectScript), but COS uses it in other ways as well.

Set the variable X to a value of +12

Set X=+12
Write X
12

Set the variable X to the value of +"ABC"

0 1
0

comments

198

views

0

rating

NewBie's Corner Session 2 Variables Set and Write commands

Welcome to NewBie's Corner, a weekly or biweekly post covering basic Caché Material.

Session 2 – Click on the Caché Cube in your system tray and select Terminal to try out the commands.

Variables

Like other computer programming languages, Caché uses Variables and the values they represent to control programming. Variables are elements that represent data values. Manipulating and interrogating variables is at the root of programming.

  • Variable names are case-sensitive
  • Variable names should be no longer than 31 characters
  • Variable names must be either Alpha or Numeric characters. No underscores or dashes
  • Variables must start with either "%" or an alpha character (A, B, C . . . Z), lower or upper case
  • By convention, variable names that start with "%", are reserved for the system

Set command

0 3
0

comments

198

views

+ 2

rating

Hello,

I'm trying to connect to a Caché server from Atelier; the Caché server is 2015.x.

The address and port I'm trying to connect to is the SQL gateway server; and I get, each time, an "unexpected end of file from server".

Note that unfortunately, for the moment, I connect as _system... And the Caché install has the default privileges.

What am I doing wrong?

Last answer 13 May 2016
0 1
0

comments

298

views

+ 1

rating

Hi,

If you want to import data from a mySQL export file (exported with mysqldump), you will find here a little script that could help.

Only the INSERT commands in the sql file are executed into Caché. Indices are not computed for better performance.
%NOINDEX, %NOCHECK and %NOLOCK are generated on each INSERT line.

Currently, the file can not contain a "),(" pattern inside the values part of the INSERT command. If this is the case, the line is skipped. This feature may be implemented in the extractValuesList method.

Feel free to improve it as needed. Unfortunately it's not guaranty bug free for the moment!

mysql.tools.xml_0.zip

Last comment 13 May 2016
0 2
227

views

+ 2

rating

I have some logging code that outputs task status information to a log file. I would like to make the log available for reading while it is open for writing. The file is opened using the "L" option (Lock):

Open tLogFile:"WASL" Set tLogOpen=1


My intent was to prevent multiple processes from accidentally writing to the file and having messy output. Unfortunately, if the process is taking longer than expected, one can not simply open the log file to figure out what is going on because the "L" lock prevents the file from being opened for reading as well as writing.

Is there a simple way to enforce a single writer but allow many readers?

I am thinking that I may just have to take out a regular COS lock when opening the file, and release the lock when closing the file, but if I can just change the flags on the Open command, I would rather know how to do that.

Thanks,

Derek

Last answer 11 May 2016
0 1
0

comments

185

views

0

rating

Hi!

Want to share with you code snippet of try catch block I usually use in methods which should return %Status. 


{ 
 try {
  	$$$TOE(sc,StatusMethod())
 }
 catch e {
 	set sc=e.AsStatus()
 	do e.Log()
 }

Quit sc 
}

Here $$$TOE is a short form of $$$TROWONERROR macro.

Inside macro StatusMethod is any method you call which will return %Status value. This value will be placed into sc variable.

In case of sc contains error execution will be routed to try catch block. You can wrap any Status methods calls in your code if you need to catch the errors coming from them.

In try catch block I place my logic and have to mandatory calls:

s sc=e.AsStatus() to get the status of error.

D e.Log()  - to place all the stack of error to standard Application Error log which you can find in Management portal on this page

Last comment 9 May 2016
0 7
1191

views

+ 2

rating

Hello,

It is time for me to eat my own dog's food and start implementing unit test running with coverage :) I will be inundating IRC with questions at this point, but I have a more general question first.

In this tutorial, it is supposed that your unit tests are exported as XML first... But that's not very practical. Is there a way, instead, to run all tests from a given project without having this export?

My first thought on how to do this would be to

Last answer 20 April 2016 Last comment 2 May 2016
0 1
325

views

+ 1

rating

Hello,

Still related to the unit test with coverage support project, one goal is to make that package available to everyone.

One possible way I already know of is that all fully qualified class names (ie, the package + the class name) start with %, which mean that on installation all classes will end up in the %SYS namespace, but this requires that the install be done as a user with the necessary privileges to write to %SYS.

This is rather convenient in my situation, sure; but is there another way which does not require such privileges? If yes, is there a way to make this package available to anybody who wants to use it?

Last answer 1 May 2016 Last comment 1 May 2016
0 1
266

views

+ 1

rating

(Possibly?) little-known fact: It's possible to use $ListBuild on the left hand side of the equals sign in a set command to extract multiple list values at once:

set $ListBuild(several,individual,variables) = list

 

For example:

USER>kill
 
USER>set colors = $ListBuild("red","orange","yellow")
 
USER>set $ListBuild(r,o,y) = colors
 
USER>write r,!,o,!,y,!
red
orange
yellow

 

See for reference: http://docs.intersystems.com/cache20152/csp/docbook/DocBook.UI.Page.cls?...

This feature was news to me - I use $ListBuild lists a lot but hadn't come across it until today. Had anyone else encountered this?

Last comment 27 April 2016
0 4
245

views

0

rating

Hello,

Here's the code:


Method isTestClass(className As %String) As %Boolean
{
    if (className = ..#UTCLASS) {
        return 1
    }
    
    #dim c as %Dictionary.ClassDefinition
    #dim status as %Status
        
    set c = ##class(%Dictionary.ClassDefinition).%OpenId(className,,.status)
    
    if ($$$ISERR(status)) {
        throw ##class(%Exception.StatusException).CreateFromStatus(status)
    }
    
    if ('c.SuperIsDefined()) {
        return 0
    }
    
    #dim children
    #dim len as %Integer
    #dim i as %Integer
    
    set children = $listFromString(c.Super, ",")
    set len = $listLength(children)
    
    for i = 1:1:len {
        if ..isTestClass($listGet(children, i)) {
            return 1
        }
    }
    
    return 0
}

One thing which bothers me here is that I do not "close" the %Dictionary.ClassDefinition object; I believe this to be a problem somewhat, is that the case

Last answer 25 April 2016 Last comment 27 April 2016
0 1
290

views

0

rating

Hello community!

Heretofore is announced a new project which aims at providing a usable library for both running unit tests and collecting code coverage information at the same time:

https://github.com/litesolutions/cache-utcov

I shamelessly admit that this is my first project written in ObjectScript; the only source file right now barely loads a %Studio.Project instance on a given namespace and fails ungracefully on failure (it HALTs; meh); and even on success it will not even list the items correctly... Well, that's part of the learning curve.

This project is of course not "innocent": for CachéQuality, we want that information (the result of unit tests and coverage information). But we believe that it is in the interest of a lot of people that a package exists which provides such information in as generic a way as possible

Last comment 21 April 2016
0 5
414

views

0

rating

We are trying to create a simple class extending %RegisteredObject that could be used as a singleton. However we are not able to store it in a global to later be retrieved (by the same process but elsewhere in the code).

I resumed my issue in this small code sample :

Last answer 19 April 2016 Last comment 20 April 2016
0 1
328

views

+ 1

rating