2.3. Class Data: shared and const

In addition to object attributes, a class definition may also contain 'shared' data, which is shared by all the objects of that class.

2.3.1. Shared Attributes - Restricted global variables

Shared attributes are similar to object attributes, but are shared between all the instances of a class. They are essentially global variables that reside within a class namespace. They can be accessed and modified by any instance of the class. Shareds can have the same private and readonly restrictions that regular attributes have
private shared i,j:INT;
readonly shared c:CHAR := 'x'

Unlike regular attributes, when only a single shared attribute is defined, a constant initializing expression may be provided.
shared s:STR := "name";
-- ILLEGAL shared s,p:STR := "name";
-- cannot use initializing expression if two shareds are
-- declared at the same time

If no initializing expression is provided, the shared is initialized to the value 'void'.

2.3.2. Class Constants

Constants are accessible by all objects in a class and may not be assigned to - they must have an initializing expression from which their value is determined at compile time (there is an exception when no type is specified, as descrbed in the next subsection). If a type is specified, then the construct defines a single constant attribute which must be initialized to a constant expression. Constant expressions are recursively composed out of a combination of literals, function calls on literals, and references to other constants. More precisely, legal assignments are to

[1] Implementation Note: The compiler currently does not always detect this illegal case.

Integer constants and Enumerated Types

If a type specifier is not provided, then no initializing expression is required and the construct defines one or more successive integer constants. The first identifier is assigned the value zero by default; its value may also be specified by a constant expression of type INT. The remaining identifiers are assigned successive integer values. This is the way to do enumeration types in Sather. It is an error if no type is specified and there is an assignment that is not of type INT.
const a;
-- a is of type INT and gets the value 0
const c,d;
-- c gets 0 and d gets 1
const e := 3;
-- e is also of type INT

Points to note

2.3.3. Accessing Class Data - the :: notation

It is possible to directly access the class data or features using the :: notation.
class FOO is
   const a:INT := 3;
   private const b:INT := 5;
   readonly shared c:INT := 6;
   shared d:INT := 7;
   attr f:INT;

   create(i:INT):SAME is
      res:SAME := new;
      res.f := i;
      return res;

   method1:INT is
      return d+a;

   method2:INT is
      return f+a;

The shared and const class data can then be accessed using the :: notation
#OUT+ FOO::a+"\n";
FOO::d := 3;

When a method is called using the '::' notation, it is equivalent to calling the method on a void object. Calling a method on a void object makes sense if the feature only makes use of shared data and local state. If the method makes use of object data, a run-time error will result.
-- Prints out d+a = 10
-- Tries to print out self.f+a
-- However, self (the object) is void, so trying to access 'f'
-- results in a run-time error - Attribute access of void