<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: John Murray</title>
    <description>The latest articles on Forem by John Murray (@gjsjohnmurray).</description>
    <link>https://forem.com/gjsjohnmurray</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F602473%2Fcf2f4aca-c941-40cd-b6ec-a8355ddcd026.jpeg</url>
      <title>Forem: John Murray</title>
      <link>https://forem.com/gjsjohnmurray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gjsjohnmurray"/>
    <language>en</language>
    <item>
      <title>Class Projections and Projection Classes</title>
      <dc:creator>John Murray</dc:creator>
      <pubDate>Tue, 21 Sep 2021 09:31:56 +0000</pubDate>
      <link>https://forem.com/intersystems/class-projections-and-projection-classes-1ecp</link>
      <guid>https://forem.com/intersystems/class-projections-and-projection-classes-1ecp</guid>
      <description>&lt;p&gt;The purpose of this post is to raise the profile of a powerful mechanism that has long been available to us, and to open a discussion about ways in which it can be used or abused.&lt;/p&gt;

&lt;p&gt;You can read more detail about the mechanism in the &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_projections"&gt;InterSystems documentation&lt;/a&gt;. To summarize, your class definition can use the Projection keyword to reference one or more projection classes. A projection class can implement methods that get invoked at key points in the lifecycle of your class.&lt;/p&gt;

&lt;p&gt;A projection class must extend &lt;a href="https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?&amp;amp;LIBRARY=%25SYS&amp;amp;CLASSNAME=%25Projection.AbstractProjection"&gt;&lt;code&gt;%Projection.AbstractProjection&lt;/code&gt;&lt;/a&gt; and will typically implement at least one or the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CreateProjection&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RemoveProjection&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;CreateProjection&lt;/code&gt; will be called after your class has been compiled. &lt;code&gt;RemoveProjection&lt;/code&gt; will be called just before your class is recompiled, or just before it is deleted.&lt;/p&gt;

&lt;p&gt;I think one of the original uses of this mechanism was to generate Java files that implemented a Java projection of an InterSystems class. Since then, it has been used more extensively and become more sophisticated. In InterSystems IRIS 2021.1 I found twenty-six %-classes that derive from &lt;code&gt;%Projection.AbstractProjection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Apart from how InterSystems uses the mechanism I have also seen it exploited in other ways. Here are a couple of examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/intersystems/UMLExplorer"&gt;UMLExplorer&lt;/a&gt; ships as an XML file containing four classes. One of these is a projection class called &lt;code&gt;ClassExplorer.WebAppInstaller&lt;/code&gt;, which ingeniously projects itself:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class ClassExplorer.WebAppInstaller Extends %Projection.AbstractProjection
{

Projection Reference As WebAppInstaller;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So when this class is compiled its &lt;code&gt;CreateProjection&lt;/code&gt; method executes, performing whatever steps the developer coded there. In this case it adds a web application called /CacheExplorer, but it could do anything that the permissions of person compiling the class allow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A site using our &lt;a href="https://georgejames.com/deltanji/"&gt;Deltanji source code management tool&lt;/a&gt; created a utility projection class. Whenever they are deploying a piece of work that requires some installation steps to run in a target namespace, they implement those steps in a deployment class (D) that has a projection referencing their utility projection class (P). Then they bundle (D) with the piece of work. When (D) gets loaded and compiled in a target namespace the CreateProjection method of (P) is automatically invoked, and is passed the classname (D), allowing it to invoke methods of (D).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've seen projection used in other ways, or if you've devised a novel use yourself, please share it as a comment on this post.&lt;/p&gt;

&lt;p&gt;One more thought from me at this point. The mechanism means we should probably think twice before compiling during import an XML file whose contents we aren't sure we can trust. The scope for a malicious projection class is great.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Running OS-level commands from the InterSystems IRIS command prompt</title>
      <dc:creator>John Murray</dc:creator>
      <pubDate>Tue, 23 Mar 2021 18:45:55 +0000</pubDate>
      <link>https://forem.com/intersystems/running-os-level-commands-from-the-intersystems-iris-command-prompt-819</link>
      <guid>https://forem.com/intersystems/running-os-level-commands-from-the-intersystems-iris-command-prompt-819</guid>
      <description>&lt;p&gt;I originally posted this tip a few years ago on &lt;a href="https://community.intersystems.com/post/terminal-tip-running-os-level-commands"&gt;InterSystems Developer Community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When working at the IRIS (or Ensemble or Caché) command prompt I sometimes want to run an operating system command on the server host. By prefixing my command line with &lt;code&gt;!&lt;/code&gt; or &lt;code&gt;$&lt;/code&gt; I can do this with ease. The following examples are from 2020.1 on Windows, but I think the feature is available on all versions and platforms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USER&amp;gt;!dir

 Volume in drive C is Windows
 Volume Serial Number is XXXX-XXXX

 Directory of c:\intersystems\iris201\mgr\user

11/12/2020  17:31    &amp;lt;DIR&amp;gt;          .
11/12/2020  17:31    &amp;lt;DIR&amp;gt;          ..
23/03/2021  14:00         1,048,576 IRIS.DAT
14/03/2021  10:00                37 iris.lck
11/12/2020  17:30    &amp;lt;DIR&amp;gt;          stream
               2 File(s)      1,048,613 bytes
               3 Dir(s)  134,542,090,240 bytes free
USER&amp;gt;$dir

 Volume in drive C is Windows
 Volume Serial Number is XXXX-XXXX

 Directory of c:\intersystems\iris201\mgr\user

11/12/2020  17:31    &amp;lt;DIR&amp;gt;          .
11/12/2020  17:31    &amp;lt;DIR&amp;gt;          ..
23/03/2021  14:00         1,048,576 IRIS.DAT
14/03/2021  10:00                37 iris.lck
11/12/2020  17:30    &amp;lt;DIR&amp;gt;          stream
               2 File(s)      1,048,613 bytes
               3 Dir(s)  134,542,159,872 bytes free
USER&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I need to issue more than one command I can &lt;em&gt;almost&lt;/em&gt; get myself an interactive shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USER&amp;gt;!

c:\intersystems\iris201\mgr\user\&amp;gt; dir
 Volume in drive C is Windows
 Volume Serial Number is XXXX-XXXX

 Directory of c:\intersystems\iris201\mgr\user

11/12/2020  17:31    &amp;lt;DIR&amp;gt;          .
11/12/2020  17:31    &amp;lt;DIR&amp;gt;          ..
23/03/2021  14:00         1,048,576 IRIS.DAT
14/03/2021  10:00                37 iris.lck
11/12/2020  17:30    &amp;lt;DIR&amp;gt;          stream
               2 File(s)      1,048,613 bytes
               3 Dir(s)  134,542,151,680 bytes free
c:\intersystems\iris201\mgr\user\&amp;gt; date
The current date is: 23/03/2021
Enter the new date: (dd-mm-yy)
c:\intersystems\iris201\mgr\user\&amp;gt; exit
USER&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wrote "almost" because in the example above the &lt;code&gt;date&lt;/code&gt; command prompted me to enter a new date but didn't wait for my keystrokes. It behaved as though I had immediately pressed Enter.&lt;/p&gt;

&lt;p&gt;Still, I find it a useful feature.&lt;/p&gt;

&lt;p&gt;To use it you will need the %System_Callout:USE privilege.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
