On Jun 25, 2015, at 12:44 PM, Guy Duff wrote:

> Hi, and thanks for having this forum. I am reading the book entitled 
> beginning node.js by  Basarat Ali Syed.   There is a code example that I am 
> having a little trouble understanding:
> 
> function printableMessage() {
>       var message = 'hello';
>       function setMessage(newMessage) {
>               if(!newMessage) throw new Error('cannot set empty message');
>               message = newMessage;
>       }
> 
>       function getMessage() {
>               return message;
>       }
> 
>       function printMessage() {
>               console.log(message);
>       }
> 
>       return {
>               setMessage: setMessage,
>               getMessage: getMessage,
>               printMessage: printMessage
>       };
> }
> 
> // Pattern in use
> var awesome1 = printableMessage();
> awesome1.printMessage();
> 
> var awesome2 = printableMessage();
> awesome2.setMessage('A new message for you.');
> awesome2.printMessage();
> "
> 
> I understand everything except the syntax in the return section.  Why is the 
> label the same as function name in each case in the return section.   Why is 
> a return necessary to execute the function at all?  This code was designed to 
> illustrate the concept of "revealing modules"?  I would be very grateful if 
> anyone can elaborate on how this example reveals modules.  Are each of the 
> functions a "module"?  If this is so, am I to assume that the return function 
> is responsible for revealing them?
> 
> It seems like the functions are methods of the printableMessage function?  
> Anyway, sorry for asking such a nube question.  I really want to understand 
> node.js, not just hack into to develop.  - Thanks very much.

In this example, "printableMessage" is a function. setMessage, getMessage, and 
printMessage are private functions inside the printableMessage function. 
Normally you wouldn't be able to get access to those functions from outside the 
printableMessage function, but in this case you can, because printableMessage 
returns an object whose properties are references to those private functions, 
thus "revealing" them outside of the printableMessage function.

To break down the return statement that you asked about:

>       return {
>               setMessage: setMessage,
>               getMessage: getMessage,
>               printMessage: printMessage
>       };

It's returning a new object, as indicated by the curly braces. If it just said 
"return {};" that would be returning a new empty object. If it said "return 
{name: 'Ryan', color: 'Blue'};" that would be returning a new object with two 
keys: the key "name" with the string value "Ryan" and the key "color" with the 
string value "Blue". But in this case it's returning a new object with three 
keys -- "setMessage", "getMessage", and "printMessage", and the values of each 
of the keys are not strings but rather the private functions defined earlier.

I'm not sure if it is necessarily proper to call them "methods", because the 
word "method" only applies to a class, and printableMessage is not a class, 
strictly speaking. (You do not instantiate instances of printableMessage with 
the "new" operator.) But it does have a similar purpose to a class so maybe 
it's ok to call them methods.

Conceptually, this printableMessage function is what's called a factory. When 
you call the function, it returns something to you that you can use as an 
instance of a class (and each time you call it, it makes a new object / a new 
instance). Usually, factory functions are named to make their purpose clear. 
For example, it might be more properly named printableMessageFactory.

In node, a module is usually a separate file. So you might have a file 
printableMessage.js to define the printableMessage module, like this:


function printableMessage() {
        var message = 'hello';

        function setMessage(newMessage) {
                if(!newMessage) throw new Error('cannot set empty message');
                message = newMessage;
        }

        function getMessage() {
                return message;
        }

        function printMessage() {
                console.log(message);
        }

        return {
                setMessage: setMessage,
                getMessage: getMessage,
                printMessage: printMessage
        };
}

module.exports = printableMessage;


Then in another file, let's say index.js, you can include that module and use 
it, like this:


var printableMessage = require('./printableMessage.js');

var awesome1 = printableMessage();
awesome1.printMessage();

var awesome2 = printableMessage();
awesome2.setMessage('A new message for you.');
awesome2.printMessage();



-- 
Job board: http://jobs.nodejs.org/
New group rules: 
https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
--- 
You received this message because you are subscribed to the Google Groups 
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/nodejs/52B03E2F-F7B1-4FF6-936B-8D12F383EA33%40ryandesign.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to