Skip to content

Case switching

Leon Starr edited this page Sep 5, 2021 · 7 revisions

The ? operator, when appended to a scalar variable typed with an enumeration, designates a decision based on the variable value, much like a case/switch statement that you might find in a programming language.

Since Scrall does not support literal values, cases are only represented by enumeration values. Consequently, you must specify a case for each possible value of an enumeration type.

vehicle traversing intersection ?
    traffic signal? {
        .red : take photo -> camera
        : conserve power -> camera  // yellow and green
}

In the above example, there is one explicit case red and then an “other” case which designates all other possible enumeration values. The traffic signal variable must have an enumeration type. You could also have done this for the second case:

.green, .yellow : conconserve power -> camera

It is generally best practice to avoid use of the “other” case since its use makes it unclear that all other options were fully considered by the modeler.

Here, all possible values are made explicit:

valve position? {
	.open : close -> my valve
	.closed : open -> my valve
}

In the following example cases and guards and sequence tokens are combined:

dir? {
	// update attribute value only if input dir is different
    .up:
        !Calling up? Calling up.set <new call>
    .down:
        !Calling down? Calling down.set <new call>
}

<new call> /R38/Bank Level.Request cabin()

Each case uses a local attribute value Calling up or Calling down as a guard. If the input value and attribute value match, the local attribute is set to true (via the .set boolean operation) and the new call sequence token is enabled. Otherwise, no change occurs and no further action is necessary. If the sequence token is enabled, the Request cabin() method is invoked.

If 'dir' is not of type Direction, there will be a static error. Therefore, there is no need for a default or fall-through case.

Boolean cases

Consider cases on an enumeration with only two possible outcomes:

valve position? { .open : close -> my valve .closed : open -> my valve }

Now let’s say that we change the switch variable to a boolean scalar named valve open. You can then use a shorter guard expression:

valve open ? close -> : open -> my valve

Either formulation works.

Subclass cases

A superclass instance’s activity may behave differently depending on the associated subclass instance. The ? symbol can be postfixed on a generalization relationship name to generate a case for each modeled subclass name on that relationship.

You can then switch based on the subclass as shown:

R1? {
   .Fixed Wing Aircraft:  // must be a subclass name on R1
       // land on runway
   .Rotary Wing Aircraft:
       // land on helipad
}

If no instance is specified, the local instance is assumed. Otherwise, make the source instance explicit:

some aircraft/R1? {
   // subclass cases
}

Introduction

Model semantics

Flows (as Variables)

Constants and literals

Structure of an activity

Accessing the class model

Data flow


Grammar and parsing notes

Components

Clone this wiki locally