Statements

From Monster Wiki

Jump to: navigation, search

Contents

Code block

A code block is a collection of statements that are executed sequentially. The block is surrounded by { and }, and may contain any number of statements and variable declarations inside:

{
   vardeclaration;
   statement;
   ...
}

Variables declared inside the a code block are local to the block. They are only visible inside the block, and only after the actual declaration.

{   
    i = 1; // error
    int i;
    i = 2; // ok
}
i = 3;     // error

Import statement

You can import the scope (variables, functions, types, etc) from a class into any other scope:

class MyClass;
 
import Class1;   // Import Class1 into the class scope
 
func()
{
  {
    import Class2; // Import Class2 into local scope
  }
  // Class2 is no longer imported here.
}

Modules, singletons and normal classes can all be imported. All members of the imported class become available in the current scope:

import Class1; // contains variable x and function y()
x = 3;         // is equivalent with:
Class1.x = 3;
y();           // is equivalent with:
Class1.y();

Unless Class1 is a singleton or a module, this example will only work for static members of Class1, since no object is provided.

Importing multiple classes

Several classes may be imported in one statement:

import Cls1, Cls2, Cls3;
// equivalent with:
import Cls1;
import Cls2;
import Cls3;

Import and inheritance

All names imported into a scope are also available in all sub scopes. Specifically, all imports into a class will automatically be available in subclasses as well.

class A;
import Class1; // Will be available in all subclasses of A
 
func()
{
  // Class 1 is also available here, since the function is a sub scope of the class scope
  import Class2;
  {
    // Class1 and Class2 are both available here
  }
}

Conflicts

All name clashes between different scopes are handled by two simple rules:

  • conflict between imported and local names: If an imported name conflicts with a local name, the local name is always given priority. The imported name is ignored.
  • conflict between two (or more) imported names: If two imports provide the same identifier, it is an error to use the identifier (unless rule 1 applies).

The rationale behind rule 2 is to catch bugs as early as possible, and to force the user to be explicit when there is ambiguity. You can always specify which scope to use explicitly by using Classname.identifier. Example:

import Cls1; // contains 'x'
int x;
x = 3; // Uses local int x, ignores the import
 
Import ClsA, ClsB; // both contain 'y'
y = 4;         // error
ClsA.y = 4;    // ok

Again, this example only makes sense if Cls1/ClsA are modules/singletons, or if 'x' and 'y' are static members.

With statement

The with statement is an alternative way of importing into a local scope:

with(SomeClass)
{
  // use members of SomeClass here
}
// is exactly equivalent to:
{
  import SomeClass;
  // use members of SomeClass here
}

You can not use with at the class level, only inside functions and code blocks.