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

« Commas in a string, that is... || Changing the colour of part... »


antivirus | apache | asp | blogging | browser | bugtracking | cms | crm | css | database | ebay | ecommerce | google | hosting | html | java | jsp | linux | microsoft | mysql | offshore | offshoring | oscommerce | php | postgresql | programming | rss | security | seo | shopping | software | spam | spyware | sql | technology | templates | tracker | virus | web | xml | yahoo | home