Last active
July 8, 2022 21:20
-
-
Save naartjie/9005e81811c4df6a595b to your computer and use it in GitHub Desktop.
Moonscript Object accessors extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| getters = (cls, getters) -> | |
| cls.__base.__index = (key) => | |
| if getter = getters[key] | |
| getter @ | |
| else | |
| cls.__base[key] | |
| setters = (cls, setters) -> | |
| cls.__base.__newindex = (key, val) => | |
| if setter = setters[key] | |
| setter @, val | |
| else | |
| rawset @, key, val | |
| { :getters, :setters } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { :getters, :setters } = require('object_ext') | |
| describe 'object accessors', -> | |
| object1, object2, spy, spies = nil | |
| class MyObject | |
| getters @, | |
| field1: => | |
| spy 'get', key | |
| @_field1 | |
| setters @, | |
| field1: (val) => | |
| spy 'set', 'field1', val | |
| @_field1 = val | |
| before_each -> | |
| object1 = MyObject! | |
| object2 = MyObject! | |
| spies = {} | |
| spy = (fun, key, val) -> | |
| table.insert(spies, {:fun, :key, :val}) | |
| it 'should set and get simple properties', -> | |
| assert.Same #spies, 0 | |
| assert.Nil object1.field1 | |
| assert.Same #spies, 1 | |
| assert.Same spies[1], {fun: 'get'} | |
| object1.field1 = 'two' | |
| assert.Same #spies, 2 | |
| assert.Same spies[2], {fun: 'set', key: 'field1', val: 'two'} | |
| it 'should keep properties separate for separate objects', -> | |
| assert.Same #spies, 0 | |
| assert.Nil object1.field1 | |
| assert.Nil object2.field1 | |
| assert.Same 2, #spies | |
| assert.Same 'get', spies[1].fun | |
| assert.Same 'get', spies[2].fun | |
| object1.field1 = 'boo' | |
| assert.Same 3, #spies | |
| assert.Same 'set', spies[3].fun | |
| assert.Nil object2.field1 | |
| assert.Same 4, #spies | |
| assert.Same 'get', spies[4].fun | |
| assert.Same 'boo', object1.field1 | |
| assert.Same 5, #spies | |
| assert.Same 'get', spies[5].fun | |
| it 'should still allow vanilla properties without accessors', -> | |
| assert.Same 0, #spies | |
| object1.field1 = 'object1.field1' | |
| object2.field1 = 'object2.field1' | |
| object1.some_vanilla_prop = 'object1.some_vanilla_prop' | |
| object2.some_vanilla_prop = 'object2.some_vanilla_prop' | |
| assert.Same 2, #spies | |
| assert.Same 'set', spies[1].fun | |
| assert.Same 'set', spies[2].fun | |
| assert.Same 'object1.some_vanilla_prop', object1.some_vanilla_prop | |
| assert.Same 'object2.some_vanilla_prop', object2.some_vanilla_prop | |
| assert.Same 2, #spies | |
| assert.Same 'object1.field1', object1.field1 | |
| assert.Same 'object2.field1', object2.field1 | |
| it 'should have the same metatable', -> | |
| assert.equal getmetatable(object1), getmetatable(object2) | |
| it 'should allow for 2 or more setters', -> | |
| ops = {} | |
| class MyObj | |
| getters @, | |
| field1: => | |
| ops[#ops+1] = 'get:field1' | |
| @_field1 | |
| field2: => | |
| ops[#ops+1] = 'get:field2' | |
| @_field2 | |
| setters @, | |
| field1: (val) => | |
| ops[#ops+1] = 'set:field1' | |
| @_field1 = val | |
| field2: (val) => | |
| ops[#ops+1] = 'set:field2' | |
| @_field2 = val | |
| obj1 = MyObj! | |
| obj2 = MyObj! | |
| obj1.field1 = 'obj1.field1' | |
| obj1.field2 = 'obj1.field2' | |
| obj2.field1 = 'obj2.field1' | |
| obj2.field2 = 'obj2.field2' | |
| assert.Same ops, { | |
| 'set:field1', 'set:field2', 'set:field1', 'set:field2' | |
| } | |
| ops = {} | |
| assert.Same 'obj1.field1', obj1.field1 | |
| assert.Same 'obj1.field2', obj1.field2 | |
| assert.Same 'obj2.field1', obj2.field1 | |
| assert.Same 'obj2.field2', obj2.field2 | |
| assert.Same ops, { | |
| 'get:field1', 'get:field2', 'get:field1', 'get:field2' | |
| } |
Author
Is the source in this gist free-use? I imagine, considering the age, that you don't much care but I figured I'd ask just in case as I've been toying around with moonscript and have found it useful to build off of.
Author
@SleepyFugu yeah ditto (the age part).
This is forked from https://gist.github.com/kress95/13bc1001f817a42590fa.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
An extension which allows you to use getters and setters with your Moonscript objects.
Caveat: it does not use getters and setters from the super class, only base class is supported for now. Please see here for a discussion.