Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Revealing Module Pattern

1684357458

Edited 1684359721
John
Pro
I'm still new to script writing and very new to Javascript.  I have a couple simple scripts under my belt, but nothing that's ready for public consumption. I was looking at the Revealing Module Pattern from the API:Cookbook , which seems to be used by a number of the big names in script writing. I think I understand most of what it is doing (although I'm probably fooling myself about that).  I copied it verbatim into an API script and ran it, and also I also ran it with Node.js (after changing the logs to console.logs). Here's the code as copied from the Cookbook: var myRevealingModule = myRevealingModule | | ( function () { var privateVar = 'This variable is private' , publicVar = 'This variable is public' ; function privateFunction () { log (privateVar); } function publicSet (text) { privateVar = text; } function publicGet () { privateFunction (); } return { setFunc: publicSet, myVar: publicVar, getFunc: publicGet }; }()); log (myRevealingModule. getFunc ()); // "This variable is private" myRevealingModule. setFunc ( 'But I can change its value' ); log (myRevealingModule. getFunc ()); // "But I can change its value" log (myRevealingModule.myVar); // "This variable is public" myRevealingModule.myVar = 'So I can change it all I want' ; log (myRevealingModule.myVar); // "So I can change it all I want" When I run it I get the following output: "This variable is private" undefined "But I can change its value" undefined "This variable is public" "So I can change it all I want" I am wondering why I am getting the two "undefined" lines in the output.  I believe this is due to the fact that privateFunction() has a log() call in it, but the call to getFunc() is wrapped in a log() call as well, and getFunc() doesn't return anything. It seems the call should be simply: myRevealingModule. getFunc (); // "This variable is private" Am I understanding this correctly? Thanks. -- John
1684358135
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Hi John! A user named Tom did a very deep and methodical exploration of the Revealing Module Pattern several years back, starting from the viewpoint of a novice. You may find this thread helpful.
Thanks, Keith. That thread does a good job of explaining the Revealing Module Pattern.  I'm wondering specifically about why I am getting "undefined" in the output when I run the cookbook code.  Rereading my post I can see I did not make that very clear.  I'll edit my original post. -- John
1684364491
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
No worries. To be honest, I didn't read the post carefully, myself. I'm a very "fly by the seat of my pants" coder,. I just saw the subject and remembered that thread so I linked it. I leave it to the folks who do this for a living to do the deep explaining. :) I'm sure one of them will be along momentarily to do a much better job than I could.
1684367303
timmaugh
Pro
API Scripter
Just with a quick read, your closing syntax is out of order... You have: }()); What you want is: })(); Also, you are logging getFunc, which is returning privateFunction. privateFunction is logging during the course of running (the log statement that has text), but it not returning anything -- or, more properly, it is therefore returning undefined. Which you log if you invoke the getFunc via the log statement. It would seem to make more sense that your privateFunc would be a getter, and return the value of the private variable... since that is the expectation you'd have when you ran getFunc.
1684371882

Edited 1684372126
The Aaron
Roll20 Production Team
API Scripter
Tim, "um, actually..."  that syntax is fine with function(), but breaks with ()=>{}.  =D  That code was written pre-ES6. I probably wrote that code a decade ago or so, and it's not particularly good... =D  Here's a corrected version: var myRevealingModule = myRevealingModule || (function() { let privateVar = 'This variable is private'; let publicVar = 'This variable is public'; function privateFunction() { return privateVar; } function publicSet(text) { privateVar = text; } function publicGet() { return privateFunction(); } return { setFunc: publicSet, getFunc: publicGet, myVar: publicVar }; }()); // Using functions exposed by the RevealingModulePattern to get and set the privatge variable log(myRevealingModule.getFunc()); // "This variable is private" myRevealingModule.setFunc('But I can change its value'); log(myRevealingModule.getFunc()); // "But I can change its value" // accessing the privateVar doesn't work log(myRevealingModule.publicVar) // undefined // accessing the exposed variable log(myRevealingModule.myVar); // "This variable is public" myRevealingModule.myVar = 'So I can change it all I want'; log(myRevealingModule.myVar); // "So I can change it all I want" To answer your questions about the original version, as Tim points out, the undefined output is coming from calling log() on a function that doesn't return anything.  In javascript, uninitialized variables have the special value undefined. let foo; if(undefined === foo) { log("yup, foo is undefined"); } foo = "something"; if(undefined === foo) { log("won't get here..."); } log(`What is foo? ${foo}`); // logs "What is foo? something"
1684375631
timmaugh
Pro
API Scripter
"Oh, ho, ho! So there you were: programming. Before ES6." Ha. I learned something, then. I don't use the function expression form much.
1684376266
The Aaron
Roll20 Production Team
API Scripter
BTW, here's my current template for making scripts:&nbsp; <a href="https://app.roll20.net/forum/permalink/9790892/" rel="nofollow">https://app.roll20.net/forum/permalink/9790892/</a> &nbsp;and some other discussion. Here are some useful links if you're learning Javascript (particularly Roll20's particular dialect): <a href="https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern" rel="nofollow">https://app.roll20.net/forum/post/6605115/namespaces-novice-seeks-help-exploring-the-revealing-module-pattern</a> &nbsp; (Keith posted this above) <a href="https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1" rel="nofollow">https://app.roll20.net/forum/post/6584105/creating-an-object-that-holds-specific-character-dot-id-and-character-name/?pagenum=1</a> &nbsp; <a href="https://app.roll20.net/forum/post/6237754/slug%7D" rel="nofollow">https://app.roll20.net/forum/post/6237754/slug%7D</a> &nbsp;
Thanks for all the information, everyone, and thanks for the templates, Aaron.&nbsp; I've looked through those links before but I haven't managed to grok it all yet. I have to say when it comes to Javascript, I'm sometimes left baffled.&nbsp; I've been a programmer for 40 years (almost all strictly typed languages like C++ and Java) and Javascript's syntax and innate 'design patterns' often leave me confused.&nbsp; It's frustrating to look at code and have no idea what it's doing.&nbsp; I'm using it as an excuse to learn something new.&nbsp; I get to combine two of my favorite things: programming and gaming. Cheers -- John
1684421239
The Aaron
Roll20 Production Team
API Scripter
Sweet!&nbsp; I'm also a C++ programmer, and I had the exact same head scratching befuddlement when I started writing Roll20 API Scripts.&nbsp; Feel free to hit me up if you have any questions at all!&nbsp; I'll talk about code till I'm blue in the face. =D I found Javascript: The Good Parts by Douglas Crockford super helpful in my initial journey.&nbsp;