A this block focuses logic on a single value. Although it may sometimes resemble method chaining or cascades in other languages, it is much more versatile. (Note: This feature has nothing to do with self, which some languages call this.)
A this block's simple mechanism consists of two aspects:
- implicit definition of a this variable within a block
- using operators that implicitly rely on the this variable
Implicit this Variable
A this block is simply an expression followed by a code block. Throughout the block, the variable this is understood to hold the evaluated value of that expression.
// Calculate the value of 'this' (0.174533) Float.Pi/180 quarter = 90 * this // Use 'this' to convert to radians acute = 10 * this
The above example is short-hand for:
do imm this = Float.Pi/180 quarter = 90 * this // Use 'this' to convert to radians acute = 10 * this
Since this blocks can be nested within each other, the value of this for any statement refers to the inner-most this block's expression's value.
'.' Prefix Operator
The convenience of a this block comes from using operators which implicitly work with the value of this. The most common of these is the dot ('.') operator, used to call methods or access fields.
Normally, the '.' operator specifies some data object to the left, on which a method might be invoked or whose field is accessed. However, if no object is specified to the left of '.', this is assumed. It is common to find this block logic taking advantage of this shortcut:
// Normalize point to unit length point imm len = (.x * .x + .y * .y).sqrt if len > 0 .x /= len .y /= len
This example uses .x and .y to access fields in point. This works because this block assigns this to the value of point, and .x is equivalent to this.x. The block's logic is cleaner and easier to read without having to place point ahead of every dot operator.
Why is this approach is more versatile than method chaining or cascades?
- Called methods need not return self, as method chaining requires.
- Method calls may appear at any point in the block logic, instead of having to be sequenced together.
- It supports field access as well as method calls.
'<-' Prefix Operator
The <- operator adds the element on the right to the collection on the left. If no collection is specified on the left, this is assumed.
// numbers is a vector of floating-point numbers myScene.numbers <- 3.4 <- 2.6 <- 1.4 .sort
This appends three floating point numbers to the list of numbers held in myscene.numbers and then re-sorts the numbers list by calling the sort method.
Note: If we just want to add three numbers without sorting:
myScene.numbers <- [ 3.4 2.6 1.4 ]
The ':' operator
Within a this, the ':' operator may be used to replace a collection's member at some specific index with another value:
myScene.numbers 4: 1.6 // Equivalent to: myScene.numbers = 1.6 6: 1.9 <- 3.4 // Append a new number to the list of numbers .sort // Sort the list of numbers