1 There is no re-entrancy guard: a metamethod which re-enters the operation it 2 customizes re-dispatches itself until the VM's call depth limit is exceeded, 3 which raises "Too much recursion" instead of hanging or crashing. 4 5 -- Testcase -- 6 {% 7 let get = proto({}, { __get__(key) { return this[key]; } }); 8 let set = proto({}, { __set__(key, val) { this[key] = val; } }); 9 10 for (let o in [ get, set ]) { 11 try { 12 o.x; 13 o.x = 1; 14 } 15 catch (e) { 16 print(e, "\n"); 17 } 18 } 19 20 print("alive\n"); 21 %} 22 -- End -- 23 24 -- Expect stdout -- 25 Too much recursion 26 Too much recursion 27 alive 28 -- End -- 29 30 An exception raised by a metamethod fails the operation and propagates to 31 its caller, for reads, writes and deletes alike, and leaves the VM usable. 32 33 -- Testcase -- 34 {% 35 let o = proto({}, { 36 __get__(key) { die("get:" + key); }, 37 __set__(key, val) { die("set:" + key); }, 38 __delete__(key) { die("del:" + key); } 39 }); 40 41 try { o.a; } catch (e) { print(e, "\n"); } 42 try { o.a = 1; } catch (e) { print(e, "\n"); } 43 try { delete o.a; } catch (e) { print(e, "\n"); } 44 try { o.a += 1; } catch (e) { print(e, "\n"); } 45 try { print("never\n", o.a); } catch (e) { print(e, "\n"); } 46 47 print("alive\n"); 48 %} 49 -- End -- 50 51 -- Expect stdout -- 52 get:a 53 set:a 54 del:a 55 get:a 56 get:a 57 alive 58 -- End -- 59 60 A nested dispatch on a different key is an ordinary recursive lookup and 61 returns. 62 63 -- Testcase -- 64 {% 65 let o = proto({}, { 66 __get__(key) { 67 return key == "a" ? this.b : "value:" + key; 68 } 69 }); 70 71 print(o.a, " ", o.b, "\n"); 72 %} 73 -- End -- 74 75 -- Expect stdout -- 76 value:b value:b 77 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt