• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/tests/custom/06_metamethods/10_set

  1 The `__set__` metamethod is consulted when a property is assigned which is
  2 not already an own property of the object. It is invoked as a method on the
  3 instance, with the key and the value as arguments.
  4 
  5 -- Testcase --
  6 {%
  7         let log = [];
  8 
  9         let o = proto({ own: 1 }, {
 10                 __set__(key, val) {
 11                         push(log, key + "=" + val);
 12                         rawset(this, "backing:" + key, val);
 13                 }
 14         });
 15 
 16         o.nw = 2;
 17         o.own = 3;
 18 
 19         print(rawget(o, "backing:nw"), " ", o.own, "\n");
 20         print(log, "
 21 ");
 22 %}
 23 -- End --
 24 
 25 -- Expect stdout --
 26 2 3
 27 [ "nw=2" ]
 28 -- End --
 29 
 30 An assignment evaluates to the assigned value, not to whatever the invoked
 31 `__set__` returns.
 32 
 33 -- Testcase --
 34 {%
 35         let o = proto({}, {
 36                 __set__(key, val) {
 37                         rawset(this, key, val * 2);
 38                         return "ignored";
 39                 }
 40         });
 41 
 42         print((o.x = 21) === 21, " ", o.x, "\n");
 43 %}
 44 -- End --
 45 
 46 -- Expect stdout --
 47 true 42
 48 -- End --
 49 
 50 Object literals store their members without dispatching `__set__`, including
 51 a metamethod of the very same object.
 52 
 53 -- Testcase --
 54 {%
 55         let o = {
 56                 __set__(key, val) {
 57                         die("intercepted " + key);
 58                 },
 59                 a: 1,
 60                 b: null
 61         };
 62 
 63         print(o.a, " ", o.b === null, " ", length(keys(o)), "\n");
 64 %}
 65 -- End --
 66 
 67 -- Expect stdout --
 68 1 true 3
 69 -- End --
 70 
 71 A null value is stored and read back like any other value.
 72 
 73 -- Testcase --
 74 {%
 75         let o = proto({ n: null }, { __get__(key) { return "virtual"; } });
 76 
 77         print(o.n === null, " ");
 78 
 79         o.a = 1;
 80         o.a = null;
 81         print(o.a === null, " ", rawget(o, "a") === null, " ");
 82 
 83         rawset(o, "b", null);
 84         printf("%.J\n", keys(o));
 85 %}
 86 -- End --
 87 
 88 -- Expect stdout --
 89 true true true [
 90         "n",
 91         "a",
 92         "b"
 93 ]
 94 -- End --
 95 
 96 A `__set__` which is itself an object (rather than a function) delegates the
 97 store to that object.
 98 
 99 -- Testcase --
100 {%
101         let target = {};
102         let o = proto({}, { __set__: target });
103 
104         o.x = 42;
105         o.y = "hello";
106 
107         print(target.x, " ", target.y, "\n");
108         print(rawget(o, "x") === null, "\n");
109 %}
110 -- End --
111 
112 -- Expect stdout --
113 42 hello
114 true
115 -- End --
116 
117 A delegated store re-dispatches the target's own metamethods, so a chain of
118 delegation reaches the final storage.
119 
120 -- Testcase --
121 {%
122         let store = {};
123         let mid = proto({}, { __set__(key, val) { store[key] = val; } });
124         let o = proto({}, { __set__: mid });
125 
126         o.n = 7;
127 
128         print(store.n, " ", rawget(o, "n") === null, "\n");
129 %}
130 -- End --
131 
132 -- Expect stdout --
133 7 true
134 -- End --
135 
136 Arrays with their own prototype take part in `__set__` delegation for non-index
137 keys just like objects do.
138 
139 -- Testcase --
140 {%
141         let target = {};
142         let a = proto([10, 20], { __set__: target, __get__: target });
143 
144         a[0] = 99;
145         a.name = "lan";
146 
147         print(a[0], " ", a.name, " ", target.name, "\n");
148 %}
149 -- End --
150 
151 -- Expect stdout --
152 99 lan lan
153 -- End --

This page was automatically generated by LXR 0.3.1.  •  OpenWrt