File: properties.md

package info (click to toggle)
surgescript 0.5.4.4-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,876 kB
  • sloc: ansic: 13,674; makefile: 16
file content (145 lines) | stat: -rw-r--r-- 3,033 bytes parent folder | download | duplicates (3)
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;
}
```