1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
Properties
==========
Introduction
------------
In SurgeScript, [object-level variables](/tutorials/variables) are private. This means that these variables can only be accessed from the objects that defined them. However, SurgeScript features a *syntactic sugar* that allows objects to read and/or modify other objects' data in a way that looks like dealing with regular (public) variables. We'll call these "variables" **properties**.
Defining properties
-------------------
Suppose you have an object called `Animal` with an object-level variable called `sound` and a function named `speak()`:
```
object "Animal"
{
sound = "meow!";
fun speak()
{
Console.print(sound);
}
}
```
This object can only speak *meow!* Let's see:
```
object "Application"
{
animal = spawn("Animal");
state "main"
{
animal.speak();
}
}
```
Run this script and you'll see:
```
meow!
meow!
meow!
meow!
...
```
What if an external object could modify the sound of the animal? Trying to access `animal.sound` externally will trigger an error, unless you add the `public` specifier to your variable:
```
object "Animal"
{
public sound = "meow!";
fun speak()
{
Console.print(sound);
}
}
```
Now, external objects may access (read and write) the `sound` variable (or *property*):
```
object "Application"
{
animal = spawn("Animal");
state "main"
{
animal.sound = "woof!";
animal.speak();
}
}
```
Since SurgeScript 0.5.3, you may add the `readonly` modifier after the `public` specifier. Doing so disallows the modification of the property by external objects:
```
object "Animal"
{
public readonly sound = "meow!";
fun speak()
{
Console.print(sound);
}
}
object "Application"
{
animal = spawn("Animal");
state "main"
{
//animal.sound = "woof!"; // will trigger an error
//Console.print(animal.sound); // this is allowed
animal.speak();
}
}
```
Using getters and setters
-------------------------
In reality, however, there are no public variables in SurgeScript. Behind the scenes, the language defines special functions called *getters* and *setters* that will perform the read/write logic for you. Rather than using `public`, you may want to define the getters and the setters yourself:
```
object "Animal"
{
sound = "meow!";
fun speak()
{
Console.print(sound);
}
fun set_sound(value)
{
sound = value;
}
fun get_sound()
{
return sound;
}
}
```
This code is semantically the same as setting `sound` to be `public`; this is just a bit longer.
An advantage of defining getters and setters by yourself is that you control how the data passes through the objects. You may want to validate the data before changing the internal variables of the objects. Example:
```
// lives must not be a negative number
fun set_lives(value)
{
if(value >= 0)
lives = value;
else
lives = 0;
}
```
|