DRY Accessor Helper
Date: 06/01/06
(Javascript Community) Keywords: html, java
I got tired of creating accessor methods for properties (as well as the properties themselves!) in my javascript classes, so, taking a note from the prototype.js library, I wrote a helper which acts a little like ruby's attr_writer and attr_reader as well as method_missing. It's loosely based upon a MockObject class written by William Tayson at http://www.jadetower.org/muses/archives/000388.html.
The library itself does not have any dependencies, although I am (for convenience sake) using it with the prototype.js Object.extend() function in the example which follows.
// Accessors
// Based on an idea from William
Tayson ( http://www.jadetower.org ):
// "Bringing method_missing to
javascript" --
//
http://www.jadetower.org/muses/archives/000388.html
//
// To create a "mixin" for
accessor methods.
//
// Part of the Tarpaulin Project
//
// tarpaulin.rubyforge.org
//
// Written by ottercat --
ottercat@ottercat.net
//
// No dependencies on other code
// a helper function used below
by multiple functions/objects
function accessorWrapper(method){
return
function(arg) {
var
property=method.substr(3);
var
mode=method.substr(0,3);
if(mode ==
"get")
{
return this[property];
}
else
{
this[property]=arg;
}
}
}
// create both a getX() and setX()
function Accessors(properties) {
properties=properties.split(/[ \t\n]+/);
for (var i=0;
i < properties.length; i++)
{
this[properties[i]]="";
getter="get"+properties[i].substr(0,1).toUpperCase()+properties[i].substr(1);
this[getter]=accessorWrapper(getter);
setter="set"+properties[i].substr(0,1).toUpperCase()+properties[i].substr(1);
this[setter]=accessorWrapper(setter);
}
}
// follow the ruby convention
here of creating a reader
function attrReader(attributes) {
properties=properties.split(/[ \t\n]+/);
for (var i=0;
i < attributes.length; i++)
{
if(this[attributes[i]] == undefined)
{
this[attributes[i]]="";
}
getter="get"+attributes[i].substr(0,1).toUpperCase()+attributes[i].substr(1);
this[getter]=accessorWrapper(getter);
}
}
// follow the ruby convention
here of creating a writer
function attrWriter(attributes) {
properties=properties.split(/[ \t\n]+/);
for (var i=0;
i < attributes.length; i++)
{
if(this[attributes[i]] == undefined)
{
this[attributes[i]]="";
}
setter="set"+attributes[i].substr(0,1).toUpperCase()+attributes[i].substr(1);
this[setter]=accessorWrapper(setter);
}
}
Here's test code, showing usage.....
var test={
fred : "flintstone",
tom : "jerry",
foo : function() {
alert("test!");}
};
Object.extend(test,new
Accessors("name rank"));
test.setName("Barney Fife");
test.setRank("Deputy");
for (i in test)
{
document.write(i + "
");
}
document.write(test.getName()+"
");
document.write(test.getRank()+"
");
I'll have this shortly posted to CVS, but what do you think?
Source: http://community.livejournal.com/javascript/101086.html