Digging into Coffeescript I am trying to port my Javascript files to Coffeescript.
Concerning this, I have a question related to the module pattern of Doulgas Crockford (closure binding in order to keep variables "private")
Therefore my question is: What would the aquivalent Coffeescript for the following JS look like:
var test = function () { var hidden = 'open'; return { open: hidden }; }();
Respectively, is there a different / better aproach to this pattern in Coffeescript?
I think the best approach is to literally translate your example into CoffeeScript, with the help of the do keyword (which exists mainly to capture values in loops—see my PragPub article):
test = do ->
hidden = 'open'
open: hidden
This compiles to
var test;
test = (function() {
var hidden;
hidden = 'open';
return {
open: hidden
};
})();
which is identical to your code other than formatting. (The CoffeeScript compiler automatically puts all var declarations at the top of their scope, which makes it easy to determine how a variable is scoped by looking at the JavaScript output.)
I added a section to the coffeescript wiki on how I handle namespacing. It's pretty elegent ( I think )
https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript
Coffeescript does not have a native module system above that of enclosing all source code files in an anonymous function. However with a bit of simple trickery you can have modules that are the envy of Ruby.
I define my modules like below
#module "foo", ->
#module "bar", ->
class #Amazing
toString: "ain't it"
The implementation of the module helper is
window.module = (name, fn)->
if not #[name]?
this[name] = {}
if not #[name].module?
#[name].module = window.module
fn.apply(this[name], [])
which you can put in another source file if you like. You can then access your classes by namespaced modules
x = new foo.bar.Amazing
wrt to your specific question I think the below jasmine spec answer it using my
module system
#module "test", ->
hidden = 10
#open = hidden
describe "test", ->
it "has no hidden", ->
expect(test.hidden?).toEqual false
it "has open", ->
expect(test.open?).toEqual true
CoffeeScript (or rather, the coffee script) automatically wraps your code within an anonymous function unless you tell it not to.
If you need to publish objects from within that anonymous closure, you can explicitly assign them to the root object; see the start of Underscore.coffee for some pointers.
http://jashkenas.github.com/coffee-script/documentation/docs/underscore.html
If you can write your module in a single class, then compiling the coffeescript with the -b option will naturally create the module pattern you're looking for.
This:
class test
hidden = 'open'
open: hidden
compiles to this:
var test;
test = (function() {
var hidden;
hidden = 'open';
test.prototype.open = hidden;
return test;
})();
which is very nearly what you were looking for.
Related
Thus far I've worked only with relatively small projects (and mostly alone), but this time I have to collaborate with other programmers... basically because of that I must plan the structure of the website very carefully for the avoidance of spending hours debugging the code.
At this point I suppose doing that in the following manner. I divide my code in modules and store each module in a separate file inside an object (or a function) with a made-up name (lzheA, lzheB, lzheC etc.) to avoid conflicts whether an object with the same name was used in an another piece of code. When the document is loaded, I declare a variable (an object) that I use as a main namespace of the application. Properties of the object are the modules I defined before.
// file BI.lib.js
var lzheA = {
foo: function() {
},
bar: function() {
},
}
// file BI.init.js
function lzheK() {
BI.loadPage();
}
// file BI.loadPage.js
function lzheC() {
var result = document.getElementById('result');
result.innerHTML = "that worked";
}
// and so on
var lzheA,lzheB,lzheD,lzheE,lzheF,lzheG,lzheH,lzheI,lzheJ;
// doing the following when the document is loaded
var BI = {
lib: lzheA,
menu: lzheB,
loadPage: lzheC,
customScripts: lzheD,
_index: lzheE,
_briefs: lzheF,
_shop: lzheG,
_cases: lzheH,
_blog: lzheI,
_contacts: lzheJ,
init: lzheK,
}
BI.init();
https://jsfiddle.net/vwc2og57/2/
The question... is this way of structuring worth living or did I miss something because of lack of experience? Would the made-up names of the modules confuse you regardless of the fact that each one used only twice - while declaring the variable and assigning it to a property?
I consider the namespaces a good option when you want to modularize applications in Javascript. But I declare them in a different way
var myModule = myModule || {}; // This will allow to use the module in other places, declaring more than one specificComponent in other js file for example
myModule.specificComponent = (function(){
// Private things
var myVar = {};
var init = function() {
// Code
};
return {
init: init // Public Stuff
};
})();
If you want to call the init method, you would call it like this
myModule.specificComponent.init();
With this approach, i guarantee that the module will not be overwritten by another declaration in another place, and also I can declare internal components into my namespaces.
Also, the trick of just exposing what you want inside the return block, will make your component safer and you will be encapsulating your code in a pretty way.
Hope it helps
I'm confused by how to use exported variables with coffeescript meteor packages.
[edit] concrete example.
I followed various advice and have a JS file _defines.js
//defines.js
Ribot = {}
Then
# server.coffee
Meteor.startup ->
Ribot = new Bot()
Meteor.methods botReply: (obj) ->
reply = Ribot.reply("user", obj.text)
so the problem is that the Ribot object within the startup block is not available inside the meteor methods block.
When i write similar code with javascript:
Meteor.startup( function() {
Ribot = new Bot();
Meteor.methods({
botReply: function(obj) {
reply = Ribot.reply("user", obj.text)
things work fine.
the current hack to get around is define everything to hang off a share.Ribot as per meteor's coffeescript support.
So for step one I don't actually need to export the Ribot object outside the package since most of the interface is currently via Meteor.methods, however I will need to eventually.
details below
There are more complicated suggestions, but I found that what works in a package is the opposite of normal CS app development.
eg:
Rbot = {} # no # on declaration
Meteor.startup ->
#RBot = new Thing() # use # in references
console.log("new Rbot", #RBot)
and then in package.js
api.export(['RBot']);
it's now available to the app.
However, in normal coffeescript usage from within my app (not a package) the opposite is true. For example
# use # when declaring
#SceneData = new Meteor.Collection("SceneData")
Meteor.startup ->
if Meteor.isServer
Meteor.publish "SceneData", (query, fields) ->
# dont use # when referencing
return SceneData.find(query, fields)
This also seems different than how normal coffeescript works outside of meteor (see ex below).
Within the app i think this is maybe because meteor is calling methods with a "this" object the same as the top level window? So there's another layer of "magic" going on?
Whereas within a package Meteor is wrapping more closures than coffeescript itself.
If someone can suggest the "right" way to do this, or explain why these two opposite wrapping/#ref styles are needed in the same framework, that'd be enlightening.
compiler example:
#outer = "outer"
inner = "inner"
p1 = () ->
console.log #outer # wont run
console.log(outer)
p2 = () ->
console.log inner
console.log #inner
p3 = () =>
console.log #outer
console.log(outer)
p1()
p2()
p3()
// compiles to:
(function() {
var inner, p1, p2, p3;
this.outer = "outer";
inner = "inner";
p1 = function() {
console.log(this.outer);
return console.log(outer);
};
p2 = function() {
console.log(inner);
return console.log(this.inner);
};
p3 = (function(_this) {
return function() {
console.log(_this.outer);
return console.log(outer);
};
})(this);
p1();
p2();
p3();
}).call(this);
If you write #myVariable = value in a package, you don't need to export myVariable since there's no package variable named myVariable, because you have instead attached it as a new property to the global object. However, you should avoid doing this, since packages shouldn't modify the global object, but exporting some of its package variables instead.
However, package variables must be defined as global variables (in JavaScript: myVariable = value (and not var myVariable = value), and the downside is that there's no equivalent statement in CoffeeScript (in CoffeeScript myVariable = value compiles to var myVariable = value, which creates a file scoped variable). To solve this, the meteor folks introduced the shared variable (containing an object), and the idea is that package scoped variable should be assigned as properties to this object. Read more about it in the docs for CoffeeScript in Meteor.
I am new to unit testing so I might be missing something, but how am I supposed to structure requirejs modules in order to make them fully testable? Consider the elegant revealing module pattern.
define([], function () {
"use strict";
var func1 = function(){
var data = func2();
};
var func2 = function(){
return db.call();
};
return {
func1 : func1
}
});
As far as I am aware of this is the most common pattern for building requirejs modules. Please correct me if I am wrong! So in this simplistic scenario I can easily test return values and behavior of func1 since it is global. However, in order to test func2 I also would have to return it's reference. Right?
return {
func1 : func1,
_test_func2 : func2
}
This makes the code slightly less pretty, but overall is still ok. However, if I wanted to mock func2 and replace its return value by using Jasmine spy I would not be able to since that method is inside a closure.
So my question is how to structure requirejs modules to be fully testable? Are there better patterns for this situation than revealing module pattern?
Are you sure you want to test the private function func2?
I think developers are missing the point of unit tests when they try writing tests for private functions.
Dependencies are what get us by the balls when developing software. And the more dependencies the tighter the squeeze . So if you have lots of tests dependant on the internal workings of a module it's going to be really painful when you want to change the internal implementation. So keep your tests dependant on the public interface, and keep the private stuff private.
My advice:
Design the public interface to your module.
Write a test against the public interface to specify some expected behaviour.
Implement the code needed to pass that test.
Refactor (if necessary)
Repeat from step 2, until all the functionality has been defined by tests, and all the tests pass.
During the implementation and refactoring stages the internals of the module will change. For example, func2 could be split up into different functions. And the danger is that if you have tests for func2 specifically, then you may have to rewrite tests when you refactor.
One of the main benefits of unit tests is that they ensure we do not break existing functionality when we change a module's internal workings. You start losing that benefit if refactoring means you need to update the tests.
If the code in func2 becomes so complex that you want to test it explicitly, then extract it into a separate module, where you define the behaviour with unit tests against the public interface. Aim for small, well tested modules that have an easy to understand public interface.
If you are looking for help with regards to unit testing I thoroughly recommend Kent Beck's book "TDD by example". Having poorly written unit tests will become a hindrance rather than a benefit, and in my opinion TDD is the only way to go.
If functions in a module call the module's other functions directly (i.e. by using references that are local to the module), there is no way to intercept these calls externally. However, if you change your module so that functions inside it call the module's functions in the same way code outside it does, then you can intercept these calls.
Here's an example that would allow what you want:
define([], function () {
"use strict";
var foo = function(){
return exports.bar();
};
var bar = function(){
return "original";
};
var exports = {
foo: foo,
bar: bar
};
return exports;
});
The key is that foo goes through exports to access bar rather than call it directly.
I've put up a runnable example here. The spec/main.spec.js file contains:
expect(moduleA.foo()).toEqual("original");
spyOn(moduleA, "bar").andReturn("patched");
expect(moduleA.foo()).toEqual("patched");
You'll notice that bar is the function patched but foo is affected by the patching.
Also, to avoid having the exports polluted by test code on a permanent basis, I've sometimes done an environmental check to determine whether the module is run in a test environment and would export functions necessary for testing only in testing mode. Here's an example of actual code I've written:
var options = module.config();
var test = options && options.test;
[...]
// For testing only
if (test) {
exports.__test = {
$modal: $modal,
reset: _reset,
is_terminating: _is_terminating
};
}
If the requirejs configuration configures my module (using config) so that it has a test option set to a true value then the exports will additionally contain a __test symbol that contains a few additional items I want to export when I'm testing the module. Otherwise, these symbols are not available.
Edit: if what bothers you about the first method above is having to prefix all calls to internal functions with exports, you could do something like this:
define(["module"], function (module) {
"use strict";
var debug = module.config().debug;
var exports = {};
/**
* #function
* #param {String} name Name of the function to export
* #param {Function} f Function to export.
* #returns {Function} A wrapper for <code>f</code>, or <code>f</code>.
*/
var _dynamic = (debug ?
function (name, f) {
exports[name] = f;
return function () {
// This call allows for future changes to arguments passed..
return exports[name].apply(this, arguments);
};
} :
_dynamic = function (name, f) { return f; });
var foo = function () {
return bar(1, 2, 3);
};
var bar = _dynamic("bar", function (a, b, c) {
return "original: called with " + a + " " + b + " " + c;
});
exports.foo = foo;
return exports;
});
When the RequireJS configuration configures the module above so that debug is true, it exports the functions wrapped by _dynamic and provides local symbols that allow referring to them without going through exports. If debug is false, then the function is not exported and is not wrapped. I've updated the example to show this method. It's moduleB in the example.
I'm trying to write 'better' javascript.
Below is one pattern I've found, and am trying to adopt. However, I'm slightly confused about its use.
Say, for example, I've got a page called "Jobs". Any JS functionality on that page would be encapsulated in something like:
window.jobs = (function(jobs, $, undefined){
return {
addNew: function(){
// job-adding code
}
}
})(window.jobs|| {}, jQuery);
$(function(){
$('.add_job').on('click', function(event){
event.preventDefault();
window.jobs.addNew();
});
});
As you can probably deduct, all I've done is replaced all the code that would have sat inside the anonymous event-handler function, with a call to a function in my global jobs object. I'm not sure why that's a good thing, other than it's reduced the possibility of variable collisions and made the whole thing a bit neater, but that's good enough for me.
The - probably fairly obvious - question is: all my event-binding init-type stuff is still sitting outside my shiny new jobs object: where should it be? Inside the jobs object? Inside the return object inside the jobs object? Inside an init() function?
I'm just trying to get a sense of a stable, basic framework for putting simple functionality in. I'm not building JS apps, I'd just like to write code that's a little more robust and maintainable than it is currently. Any and all suggestions are warmly welcomed :)
You can break down your application in whatever number of modules / objects you like too.
For instance, you can have another object / module which caches and defines all your DOM nodes and another one, which just handles any event. So for instance:
(function ( win, doc, $, undef ) {
win.myApp = win.myApp || { };
var eventHandler = {
onJobClick: function( event ) {
event.preventDefault();
myApp.addNew();
}
};
var nodes = (function() {
var rootNode = $( '.myRootNode' ),
addJob = rootNode.find( '.add_job' );
return {
rootNode: rootNode,
addJob: addJob
};
}());
$(function() {
myApp.nodes.addJob.on( 'click', myApp.handler.onJobClick );
});
myApp.nodes = nodes;
myApp.handler = eventHandler;
}( this, this.document, jQuery ));
It doesn't really matter how you create singletons in this (module) pattern, either as literal, constructor, Object.create() or whatnot. It needs to fit your requirements.
But you should try to create as many specific modules/objects as necesarry. Of course, if makes even more sense to separate those singletons / modules / objects into multiple javascript files and load them on demand and before you can say knife, you're in the world of modular programming patterns, dealing with requireJS and AMD or CommonJS modules.
Encapsulation-wise, you're fine: you could even just declare addNew in the jQuery closure and you'd still avoid the global scope. I think what you're getting at is more of implementing something close to an MVC architecture.
Something I like to do is create an object that you instantiate with a DOM element and that takes care of its own bindings/provides methods to access its controls etc.
Example:
// (pretend we're inside a closure already)
var myObj = function(args){
this.el = args.el; // just a selector, e.g. #myId
this.html = args.html;
this.bindings = args.bindings || {};
}
myObj.prototype.appendTo = function(elem){
elem.innerHTML += this.html;
this.bindControls();
};
myObj.prototype.remove = function(){
$(this.el).remove(); // using jQuery
};
myObj.prototype.bindControls = function(){
for(var i in this.bindings){ // event#selector : function
var boundFunc = function(e){ return this.bindings[i].call(this,e); };
$(this.el).on(i,boundFunc);
}
};
The way you are doing it right now is exactly how I do it also, I typically create the window objects inside the anonymous function itself and then declare inside that (in this case: jClass = window.jClass).
(function (jClass, $, undefined) {
/// <param name="$" type="jQuery" />
var VERSION = '1.31';
UPDATED_DATE = '7/20/2012';
// Private Namespace Variables
var _self = jClass; // internal self-reference
jClass = window.jClass; // (fix for intellisense)
$ = jQuery; // save rights to jQuery (also fixes vsdoc Intellisense)
// I init my namespace from inside itself
$(function () {
jClass.init('branchName');
});
jClass.init = function(branch) {
this._branch = branch;
this._globalFunctionality({ globalDatePicker: true });
this._jQueryValidateAdditions();
//put GLOBAL IMAGES to preload in the array
this._preloadImages( [''] );
this._log('*******************************************************');
this._log('jClass Loaded Successfully :: v' + VERSION + ' :: Last Updated: ' + UPDATED_DATE);
this._log('*******************************************************\n');
};
jClass._log = function() {
//NOTE: Global Log (cross browser Console.log - for Testing purposes)
//ENDNOTE
try { console.log.apply(console, arguments); }
catch (e) {
try { opera.postError.apply(opera, arguments); }
catch (e) { /* IE Currently shut OFF : alert(Array.prototype.join.call(arguments, ' '));*/ }
}
};
}(window.jClass= window.jClass|| {}, jQuery));
The reason I leave them completely anonymous like this, is that let's say in another file I want to add much more functionality to this jClass. I simply create another:
(function jClass, $, undefined) {
jClass.newFunction = function (params) {
// new stuff here
};
}(window.jClass = window.jClass || {}, jQuery))
As you can see I prefer the object.object notation, but you can use object literals object : object, it's up to you!
Either way by leaving all of this separate, and encapsulated without actual page logic makes it easier to have this within a globalJS file and every page on your site able to use it. Such as the example below.
jClass._log('log this text for me');
You don't want to intertwine model logic with your business logic, so your on the right path separating the two, and allowing for your global namespace/class/etc to be more flexible!
You can find here a comprehensive study on module pattern here: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html It covers all the aspects of block-scoped module approach. However in practice you gonna have quite a number files encapsulating you code, so the question is how to combine them property. AMD... multiple HTTP requests produced by every module loading will rather harm your page response time. So you can go with CommonJS compiled to a single JavaScript file suitable for in-browser use. Take a look how easy it is http://dsheiko.github.io/cjsc/
I'd like to write Javascript scripts for Google Apps Script using CoffeeScript, and I'm having trouble generating functions in the expected form.
Google Apps Script expects a script to contain top-level, named functions. (I may be using the wrong terminology, so I'll illustrate what I mean with examples...)
For example, this function is happily recognised by Google Apps Script:
function triggerableFunction() {
// ...
}
... while this function is not (it will parse, but won't you won't be able to trigger it):
var nonTriggerableFunction;
nonTriggerableFunction = function() {
// ...
};
I've found that with CoffeeScript, the closest I'm able to get is the nonTriggerableFunction form above. What's the best approach to generating a named function like triggerableFunction above?
I'm already using the 'bare' option (the -b switch), to compile
without the top-level function safety wrapper.
The one project I've found on the web which combines CoffeeScript and Google App Script is Gmail GTD Bot, which appears to do this using a combination of back-ticks, and by asking the user to manually remove some lines from the resulting code. (See the end of the script, and the 'Installation' section of the README). I'm hoping for a simpler and cleaner solution.
CoffeeScript does not allow you to create anything in the global namespace implicitly; but, you can do this by directly specifying the global namespace.
window.someFunc = (someParam) ->
alert(someParam)
Turns out this can be done using a single line of embedded Javascript for each function.
E.g. this CoffeeScript:
myNonTriggerableFunction = ->
Logger.log("Hello World!")
`function myTriggerableFunction() { myNonTriggerableFunction(); }`
... will produce this JavaScript, when invoking the coffee compiler with the 'bare' option (the -b switch):
var myNonTriggerableFunction;
myNonTriggerableFunction = function() {
return Logger.log("Hello World!");
};
function myTriggerableFunction() { myNonTriggerableFunction(); };
With the example above, Google Apps Script is able to trigger myTriggerableFunction directly.
This should give you a global named function (yes, it's a little hacky, but far less that using backticks):
# wrap in a self invoking function to capture global context
do ->
# use a class to create named function
class #triggerableFunction
# the constructor is invoked at instantiation, this should be the function body
constructor: (arg1, arg2) ->
# whatever
juste use # in script, exemple of my code :
#isArray = (o)->
Array.isArray(o)
it will be compiled in :
(function() {
this.isArray = function(o) {
return Array.isArray(o);
};
}).call(this);
this = window in this case, so it's global function