Mochiscript is a superset of the JavaScript language that adds more Object-Oriented features such as: methods, inheritance, mixins, etc... What this means is that Mochiscript IS Javascript. Mochiscript currently supports Ruby on Rails 3.1 (via asset pipeline) and Node.js.
More on Mochiscript features and syntax here: https://github.com/jeffsu/mochiscript/wiki/Mochiscript-Syntax
In the Gemfile, add this line:
gem 'mochiscript'
In app/assets/javascripts/application.js, add mochiscript
//= require mochiscript
Now, you should be able to create ".ms" files and it'll be included as javascript using the new rails asset pipeline.
Create a simple mochiscript (app/assets/javascripts/hello.ms):
class Hello {
function say() {
alert('hello');
}
}
Now include it in application.js
//= require hello
Now on your page, you should be able to put this code in after your javascript include section:
<script>
var obj = new Hello();
obj.say();
</script>
npm install mochiscript
In hello.ms:
export class Hello {
function say() {
console.log("hello");
}
}
In main.js:
require('mochiscript');
var Hello = require('./hello');
var obj = new Hello();
obj.say();
Parsing a file:
ms-parse <filename>
Running an ms file:
ms-run <filename>
Compiling files in a directory:
ms-watch <src> <dest> <template>
- src: source directory with .ms files
- dest: destination directory to write .js files
- template file (optional). This will allow you to templatize mochiscript. Just make sure the file has "MOCHI" in it.
Please include this file before requiring any mochiscript compiled file: mochiscript.js
Using connect/express:
var options = {
src: "views",
};
app.use(require('mochiscript').middleware(options));
Mochiscript syntax is a superset of JavaScript's. This means that any JavaScript you write will run just fine in Mochiscript. Mochiscript simply adds extra features that make development life a little easier.
Classes can be created with the "class" keyword. If you wish to have a custom initializer function, just include a method called "initialize".
class Hello {
var defaultMessage = "Just say hello";
function initialize(message) {
this.message = message || this.defaultMessage;
}
function say() {
console.log(this.message);
}
}
var obj = new Hello("what's up?");
The method "initialize" is the default instance method used to instantiate an object (just like Ruby).
class Foo {
function initialize(arg1, arg2) {
this.args = [ arg1, arg2 ];
console.log("Instance of Foo created!", arg1, arg2);
}
}
var foo = new Foo("hello", "world");
class Goodbye extends Hello {
var defaultMessage = "Goodbye";
function say() {
console.log("Saying:");
this.$super();
}
}
module World {
function world() {
console.log('world');
}
}
class HelloWorld extends Hello {
include World;
}
This is a little unorthodox part of Mochiscript which allows you to add a "closed" section that only methods in the scope of the class can access.
class MyClass {
private {
var CONSTANT_VAR = "constant";
}
function initialize(data) {
this.data = data || CONSTANT_VAR;
}
}
A lot of times, you need access to the "this" object in a callback. The problem is that "this" often points to something else in a different context. The workaround is usually:
class Foo {
var hello = "hello";
function setup() {
var self = this;
$('.hello').click(#{ alert(self.hello) });
}
}
In mochiscript, it is no longer necessary to create a "self" variable. Its given to you in all methods:
class Foo {
var hello = "hello";
function setup() {
$('.hello').click(#{ alert(self.hello) });
}
}
There are two ways to use this feature:
var myFunct = #{ console.log($1) }; // prints out first argument (supports up to 3 args)
var myFunct = #(msg){ console.log(msg) };
[ 1, 2, 3 ].map(#{ => $1 + 1 });
var array = [ 'hello', 'world' ];
foreach (var word in array) {
console.log(word);
}
// foreach with iterator
foreach (var word:i in array) {
console.log(i, word);
}
var message = <<END;
this is a lot of text
here.
END
var greetings = [ 'hi', 'hello' ];
var mapped = greetings#map { $1 + " there!" };
var some = greetings#some { $1 == 'hi' };
Mochiscript has two helpers for exporting your files:
public class MyClass {
}
// equivalent to
// exports.MyClass = MyClass;
Or make it the default export:
export class MyClass {
}
// equivalent to
// module.exports = MyClass;