A következő címkéjű bejegyzések mutatása: node. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: node. Összes bejegyzés megjelenítése

2012. december 14., péntek

Protain - defining (extending) simple classes II.

Protain also supports a "classical" syntax to create prototype chains - it doesn't look like the syntax in Java, C++ or C# or etc., but at least it is similar. So, let's do a class named Person with some methods - of course we are inside a scope of a namespace, which is refered with this:
/**
 * Person Class
 */
protain
    .class(this, 'Person')
    /**
     * @constructor
     * @param instance {Object} the new instance
     * @param name {String} the name of the instance
     */
    .init(function (instance, name) {
        instance.setName(name);
    })
    //class properties
    .define({
        /**
         * sets the name property of the context
         */
        setName: function (name) {
            //type check
            if (typeof name !== 'string' && name === '') {
                throw new TypeError('Invalid argument!');
            }

            //set the name
            this.name = name;

            //return the context
            return this;
        },
        /**
         * returns the name property of the context
         */
        getName: function () {
            return this.name;
        }
    });
Now, that we have a base class, we can extend from it using the .extend() method and .build() to build the instance with the inherited functionality:
/**
 * AgingPerson
 */
protain
    .class(this, 'AgingPerson')
    /**
     * setting up inheritance
     */
    .extend(this, 'Person')
    /**
     * @constructor
     * @param instance {Object} the new instance
     * @param name {String} the name of the instance
     * @param age {Number} the age of the instance
     */
    .init(function (instance, name, age) {
        /**
         * .build() will initialise the instance based on the inheritance and the arguments passed
         */
        this.build(arguments);

        instance.setAge(age);
    })
    .define({
        /**
         * returns the age property of the context
         */
        getAge: function () {
            return this.age;
        },

        /**
         * sets the age property of the context
         */
        setAge: function (age) {
            if (typeof age !== 'number') {
                throw new TypeError('Invalid argument!');
            }

            //set the age
            this.age = age;

            //return the context
            return this;
        }
    });
The .extend() method takes two parameters:
  • namespace - the namespace to register the extend to
  • className - the name of the class to extend

When you extend from a class, you will have to use the this.build(arguments); method inside the constructor to build the instance based on the inheritance. This method calls the base class's constructor method, just like the super() method in Java.

And then you can use the .create() method for instantiating:
var AgingPerson = protain.class(this, 'AgingPerson');

var agingPerson = AgingPerson.create('benqus', 26);
Well, I should write some more example on GitHub but so far you are good to go with Protain. =)

I hope you enjoyed these tutorials! Any question are welcome! =)

Find Protain on GitHub: https://github.com/benqus/protain

2012. december 10., hétfő

Protain - defining node-classes

So, we have arrived to the subject in which Protain tries to bring something different. Node-based class behaviour.
Sounds so advanced that I threw my brain, went after it and threw it again... =)

Let's quickly create 2 nodes in a namespace, mine will be same as in the previous tutorials - I won't comments in these now:
protain
    .node(this, 'name', {
        getName: function () {
            return this.name;
        },
        setName: function (name) {
            this.name = name;
            return this;
        }
    })
    .node(this, 'guid', function () {
        var id = 0;
    
        return {
            generateId : function () {
                this.ID = id++;
                return this;
            }
        }
    }());
First thing you want to keep in mind is that classes are able to inherit from nodes only in the same namespace!

Then when you create a class, you just "list" the nodes you want to use for that class. Also, you still have the .define or .init methods available for custom class property definitions:
/**
 * defining a "node class"
 */
protain
    .class(this, 'MyFirstNodedClass', 'guid', 'name')
    /**
     * defines a property on the class
     */
    .define({
        CLASS_NAME: 'MyFirstNodedClass'
    })
    /**
     * @constructor
     */
    .init(function (instance, name) {
        /**
         * setting some instance properties
         */
        instance
            .generateId()
            .setName(name + ' ' + (instance.ID + 1));
    });
This was very hard, right? =) Now, let's see it in action by generating 10 instances in a loop and logging it out to the console:
/**
 * instantiating 10 instances and logging them out
 */
for (var i = 0; i < 10; i++) {
    console.log(
        /**
         * logging a new instance
         */
        protain
            .class(this, 'MyFirstNodedClass')
            .create('Some random name')
    );
}
Node-based class behaviour (I'm still wet...) is quiet simple I guess... =) You are also able to extend classes from each other but that belongs to another article...

Find Protain on GitHub: https://github.com/benqus/protain

2012. december 2., vasárnap

Protain - defining simple classes I.

We arrived to the point when you would like to create a class.

Let's start by defining a simple class, nothing fancy, just a class, with a class property and a constructor. It looks like this:
protain.namespace('hu.benqus.namespace_tutorial', function (path) {
    /**
     * defining a class - simple way
     */
    protain
        /**
         * creates a class
         */
        .class(this, 'MyFirstClass')
        /**
         * defines a property on the class
         */
        .define({
            myProperty: 'myPropertyValue'
        })
        /**
         * @constructor
         */
        .init(function (instance) {
            console.log(this); //class
            console.log(instance); //instance
        });
});

Methods:

protain.class
Method creates a class object.

Arguments:
  • namespace - a protain namespace {Object}
  • class name - name of the class in {String}
  • [node1], [node2] - node names to inherit the functionality from (same namespace) {String} (see later, in the node classes article)


protain.define
Method defines a set of properties on the class object which it was invoked on.

Arguments:
  • properties - set of attributes {Object}


protain.init
Method defines a constructor function for the class. The argument method's context (this) will be the class (!!!).
First argument will be the current instance and the remaining arguments will be the passed ones in the .create() method (see later, in the instantiation article).

Arguments:
  • constructor - a constructor function to be invoked on each instantiation {Function}


This wasn't so hard after all, right? Next one will be the "noded classes", stay tuned for more dose of protain! =)

Find Protain on GitHub: https://github.com/benqus/protain

2012. december 1., szombat

Protain - nodes, concept

In this article, I would like to introduce the meaning of node in Protain.

But first, let's talk about a different approach to object-oriented programming. I named it "prototype-oriented" programming but only for myself. The first thing I would like you to forget is the idea of class, in the classical meaning. Instead, think about objects only. Of corse we are still in JavaScript!

What is a node?

In JavaScript, in prototypal-inheritance, the prototype will tell you where the instance is derived from, through the instance's prototype. Which is a reference to another object. And object properties can refer to other object's properties. That is what a node is: an object, with specified properties.

For cubes: "A node is an object's attribute collection, used by one or more classes. It's purpose is to share the same functionality between classes instead of specifying them again and again."

For example:
Suppose you have 5 different classes in the same namespace and a bunch of nodes (functionalities). You can "connect" these nodes by specifying the 5 classes. You can connect these classes differently.
Also, it is very handful when you don't have to re-model, re-design and re-implement the whole prototype-chain when you have to extend the list of functionalities.

Let's define two nodes. One in the current context-namespace and the other in the hu.benus.global namespace. We will use the protain.node method, which takes the following arguments:
  • namespace - the namespace to register the node to
  • name - the name of the node
  • object - the node as an object
protain.namespace('hu.benqus.namespace_tutorial', function (path) {
    /**
     * creating a node (functionality)
     * called 'name' containing 2 methods
     * on the current namespace
     */
    protain
        .node(this, 'name', {
            /**
             * @return {String}
             */
            getName: function () {
                return this.name;
            },
            /**
             * @param name {String}
             */
            setName: function (name) {
                this.name = name;
                return this;
            }
        });

    /**
     * creating another namespace
     * @type {Object}
     */
    var global = protain.namespace('hu.benqus.global');

    /**
     * creating a node called 'guid'
     * on the hu.benqus.global namespace
     */
    protain
        .node(global, 'guid', function () {
            /**
             * static property
             * @type {Number}
             */
            var id = 0;

            return {
                /**
                 * specifies an ID attribute for the context
                 */
                generateId : function () {
                    this.ID = id++;
                    return this;
                }
            }
        }());
});
Now, you can define as many classes as you want using the same name and guid nodes (functionalities).

Dealing with nodes is simple again, just specify the context, the name, and the node object and you are good to go.

Next one will be the class (prototype object) creation. Stay tuned for more! =)

Find Protain on GitHub: https://github.com/benqus/protain