Skip to main content

Package Options

This topic discusses packages in more detail.

For persistent classes, the package is represented in SQL as an SQL schema. For details, see Projection of Packages to Schemas.

Important:

When InterSystems IRIS® data platform encounters a reference to a class that does not include a package name and where the class name starts with “%”, InterSystems IRIS assumes the class is in the %Library package.

Overview of Packages

InterSystems IRIS supports packages, which group related classes within a specific database. Packages provide the following benefits:

  • They give developers an easier way to build larger applications and to share code with one another.

  • They make it easier to avoid name conflicts between classes.

  • They give a logical way to represent SQL schemas within the object dictionary in a clean, simple way: A package corresponds to a schema.

A package is simply a way to group related classes under a common name. For example, an application could have an Accounting system and an Inventory system. The classes that make up these applications could be organized into an Accounting package and an Inventory package:

The Accounting package has classes called Invoice and Item. The Inventory package has classes called Warehouse and Item.

Any of these classes can be referred to using their full name (which consists of package and class name):

 Do ##class(Accounting.Invoice).Method()
 Do ##class(Inventory.Item).Method()

If the package name can be determined from context (see below), then the package name can be omitted:

 Do ##class(Invoice).Method()

As with classes, a package definition exists within an InterSystems IRIS database. For information on mapping a package from a database to a namespace, see Package Mapping.

Package Names

A package name is a string. It may contain . (period) characters, but no other punctuation. Each period-delimited piece of the package name is a subpackage, and there can be multiple subpackages. If you give a class the name Test.Subtest.TestClass, then this indicates that the name of the package is Test, the name of the subpackage is Subtest, and the name of the class is TestClass.

There are several limitations on the length and usage of package names:

  • A package name is subject to a length limit. See Rules and Guidelines for Identifiers.

  • Within a namespace, each package name must be unique without regards to case. Hence, there cannot be both “ABC” and “abc” packages in a namespace, and the “abc.def” package and subpackage are treated as part of the “ABC” package.

For complete information, see Rules and Guidelines for Identifiers and What Is Accessible in Your Namespaces.

Defining Packages

Packages are implied by the name of the classes. When you create a class, the package is automatically defined. Similarly, when the last class in a package is deleted, the package is also automatically deleted.

The following shows an example in which the package name is Accounting, the class name is Invoice, and the fully qualified class name is Accounting.Invoice:

Class Accounting.Invoice 
{
}

Package Mapping

By definition, each package is part of a particular database. Frequently, each database is associated with a namespace, where the database and the namespace share a common name. To make a package definition in a database available to a namespace not associated with that database, use package mapping. This procedure is described in Adding Mappings to a Namespace.

Mapping a package across namespace maps the package definition, not its data.

Package Use When Referring to Classes

There are two ways to refer to classes:

  • Use the fully qualified name (that is, Package.Class). For example:

     // create an instance of Lab.Patient
     Set patient = ##class(Lab.Patient).%New()
  • Use the short class name and let the class compiler resolve which package it belongs to.

    By default, when you use a short class name, InterSystems IRIS assumes that the class is either in the package of the class whose code you are using (if any), or in the %Library package, or in the User package.

    If you want the compiler to search for classes in other packages, import those packages.

    Note:

    It is an error to use a short class that is ambiguous; that is, if you have the same short class name in two or more packages and import all of them, you will get an error when the compiler attempts to resolve the package name. To avoid this error, use full names.

Importing Packages

When you import packages, InterSystems IRIS looks for any short class names in those packages. In a class definition, you can import a package via the class Import directive or the ObjectScript #IMPORT directive. This section explains these directives, discusses the effect on the User package and the effect on subclasses, and presents some tips.

Class Import Directive

You can include the class Import directive at the top of a class definition, before the Class line. The syntax for this directive is as follows:

Import packages

Class name {}

Where packages is either a single package or a comma-separated list of packages, enclosed in parentheses. The word Import is not case-sensitive, but is usually capitalized as shown here.

Remember that in a class context, the current package is always implicitly imported.

ObjectScript #IMPORT Directive

In ObjectScript method, an #IMPORT directive imports a package so that you can use short class names to refer to classes in it. The syntax for this directive is as follows:

#import packagename

Where packagename is the name of the package. The word #import is not case-sensitive. For example:

#import Lab
 // Next line will use %New method of Lab.Patient, if that exists
 Set patient = ##class(Patient).%New()

You can have multiple #IMPORT directives:

#import Lab
#import Accounting

 // Look for "Patient" within Lab & Accounting packages.
 Set pat = ##class(Patient).%New()

 // Look for "Invoice" within Lab & Accounting packages.
 Set inv = ##class(Invoice).%New()

The order of #IMPORT directives has no effect on how the compiler resolves short class names.

Explicit Package Import Affects Access to User Package

Once your code imports any packages explicitly, the User package is not automatically imported. If you need that package, you must import it explicitly as well. For example:

#import MyPackage
#import User

The reason for this logic is because there are cases where you may not want the User package to be imported.

Package Import and Inheritance

A class inherits any explicitly imported packages from the superclasses.

The name of a class is resolved in the context where it was first used and not with the current class name. For example, suppose you define in User.MyClass a method MyMethod() and then you create a MyPackage.MyClass class that inherits from User.MyClass and compile this. InterSystems IRIS compiles the inherited MyMethod() method in MyPackage.MyClass — but resolves any class names in this method in the context of User.MyClass (because this is where this method was defined).

Tips for Importing Packages

By importing packages, you can make more adaptable code. For example, you can create code such as:

#import Customer1
 Do ##class(Application).Run()

Now change App.MAC to:


#import Customer2
 Do ##class(Application).Run()

When you recompile App.MAC, you will be using the Customer2.Application class. Such code requires planning: you have to consider code compatibility as well as the effects on your storage structures.

See Also

FeedbackOpens in a new tab