Coffeescript Model class with attr_accessor rails alike
Nowadays I’ve been toying around with the fabolous coffeescript language and I’ve created a basic model class.
This class allow you to use attr_accessor method as you can do in Ruby.
If you don’t know what attr_accessor is you can take a look here: Ruby attr_accessor.
Briefly what attr_accessor does is to let you access object attributes in “object.attribute” form (which in javascript is built in) but more importantly let you add a constrain on read/write permission of that attribute!
In fact if you want the attribute to be readonly you need to use the “attr_reader” method, in the opposite case you need to use the “attr_writer” method. If you don’t want to add any constraint you can use the “attr_accessor”.
Here is the code of the model:
# this creates a root namespace that works with browser or node.js
root = exports ? this
#uppercase the first letter
root.namespace.ucFirst = (field) ->
field.charAt(0).toUpperCase() + string.slice(1);
root.namespace.Model = class Model
get: (field) ->
# call getter if exists
getter = "get#{root.namespace.ucFirst(field)}"
return this[getter]() if (typeof this[getter] == "function")
@attributes[field]
set: (field, value) ->
# call setter if exists
setter = "set#{root.namespace.ucFirst(field)}"
return this[setter](value) if (typeof this[setter] == "function")
@attributes[field]=value
defineAttribute: (field, type) ->
@attributes ||= {}
prop = {}
prop[field] = {}
prop[field].get = () -> @get(field, originalGetter) unless type == "writer"
prop[field].set = (value) -> @set(field, value) unless type == "reader"
Object.defineProperties(@ , prop)
attr_accessor: (field) ->
@defineAttribute(field, "all")
attr_reader: (field) ->
@defineAttribute(field, "reader")
attr_writer: (field) ->
@defineAttribute(field, "writer")
What this code does is to create the methods: “attr_writer, attr_reader, attr_accessor”. In order to use this model you need to inherit from him in your class with “extends root.namespace.Model”. Here is an example of usage:
class Test extends root.namespace.Model
constructor: () ->
@attr_reader "readonly"
@attr_writer "writeonly"
@attr_accessor "accessor"
getTest: ->
"test"
test = new Test
# write the attribute but cannot read from him
test.writeonly = "write"
# can read from outside but cannot write
console.log test.readonly
# can read and write data
test.accessor = "writable and readable"
console.log test.accessor
#if you have a get"AttributeName" method or set"AttributeName" method it gets called instead of fetching the attribute
console.log test.test # writes "test"
That’s all forks. If you have any question or comment feel free to use the disquis form below. Enjoy.