Class Data: shared and const

Sather - A Language Tutorial
Prev | Chapter 2. Classes and Objects | Next

# 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

- a character, boolean, string, integer or floating point literal

- a `void` or `void` test expression

- an `and` or `or` expression, each of whose components is a constant expression

- an array literal, each of whose components is a constant expression

- a routine call applied to a constant expression, each of whose arguments is a constant expression other than void. This caveat is imporant, since `create` routines are called on void. Thus the following is illegal:[1]

      -- ILLEGAL const  a:POINT := #POINT(3,3);
      const a:POINT := void;
      -- The only legal kind of constant POINT is void

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

- a reference to another constant in the same class or in another class using the `'::'` notation.

      const r:FLT:=45.6;
      -- Reader routine is private r:FLT;
      private const a,b,c;
      private const d:=4,e,f
      const bar:BOOL := r > 10;
      -- Function call on constants
      const foo:ARRAY{INT} := |1,2,4,5,6|;
      -- Sather arrays are explained later
      const  baz ::= BAR::foz ;
      -- foz must be a constant expression in foz

> [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

- There must not be cyclic dependencies among constant initializers.

      class FOO is
         const b:INT := BAR::c;

      class BAR is
         const c:INT := BAZ::d;

      class BAZ is
      -- ILLEGAL!  const d:INT := FOO::b;
      -- Introduces a cycle between b, c and d

- Since constant initialization involves permits operations on the built-in types, the operations on the built-in types are designed so that no observable side-effects can occur during constant initialization.

- The prefix readonly cannot be applied to constants, since constants cannot be modified in any case.

- Due to their definition, constants are only useful for the basic classes such as numbers, booleans and characters. All other constants can only be assigned to be void!

      class FOO is
         const a:BAR := void;
         -- only legal value

## 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;
       end;

       method1:INT is
          return d+a;
       end;

       method2:INT is
          return f+a;
       end;
    end;

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.

    #OUT+FOO::method1;
    -- Prints out d+a = 10
    #OUT+FOO::method2;
    -- 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

- The usual privacy and modification restrictions are maintained

      a_copy:INT := FOO::a;
      -- ILLEGAL FOO::c :=3; -- c is readonly
      -- FOO::a := 7;  -- a is a constant

Prev | Home | Next
Defining Classes and Creating Objects | Up | Routine definitions