Coffeescript If Else Assignment Of Rents

CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

The golden rule of CoffeeScript is: “It’s just JavaScript.” The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.

Latest Version:2.2.2

Overview

CoffeeScript on the topleft, compiled JavaScript output on the bottomright. The CoffeeScript is editable!

number=42opposite=truenumber=-42ifoppositesquare=(x)->x*xlist=[1,2,3,4,5]math=root:Math.sqrtsquare:squarecube:(x)->x*squarexrace=(winner,runners...)->printwinner,runnersalert"I knew it!"ifelvis?cubes=(math.cubenumfornuminlist)
varcubes, list, math, num, number, opposite, race, square; number=42; opposite=true; if (opposite) { number=-42; } square=function(x) { returnx*x; }; list= [1, 2, 3, 4, 5]; math= { root: Math.sqrt, square: square, cube: function(x) { returnx*square(x); } }; race=function(winner, ...runners) { returnprint(winner, runners); }; if (typeofelvis!=="undefined"&&elvis!==null) { alert("I knew it!"); } cubes= (function() { vari, len, results; results= []; for (i=0, len=list.length; i<len; i++) { num=list[i]; results.push(math.cube(num)); } returnresults; })();

Installation

The command-line version of is available as a Node.js utility, requiring Node 6 or later. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see Try CoffeeScript).

To install, first make sure you have a working copy of the latest stable version of Node.js. You can then install CoffeeScript globally with npm:

This will make the and commands available globally.

If you are using CoffeeScript in a project, you should install it locally for that project so that the version of CoffeeScript is tracked as one of your project’s dependencies. Within that project’s folder:

The and commands will first look in the current folder to see if CoffeeScript is installed locally, and use that version if so. This allows different versions of CoffeeScript to be installed globally and locally.

If you plan to use the option (see Transpilation) you will need to also install either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript.

Usage

Command Line

Once installed, you should have access to the command, which can execute scripts, compile files into , and provide an interactive REPL. The command takes the following options:

OptionDescription
Compile a script into a JavaScript file of the same name.
Pipe the CoffeeScript compiler’s output through Babel before saving or running the generated JavaScript. Requires to be installed, and options to pass to Babel in a file or a with a key in the path of the file or folder to be compiled. See Transpilation.
Generate source maps alongside the compiled JavaScript files. Adds directives to the JavaScript as well.
Just like , but include the source map directly in the compiled JavaScript files, rather than in a separate file.
Launch an interactive CoffeeScript session to try short snippets. Identical to calling with no arguments.
Write out all compiled JavaScript files into the specified directory. Use in conjunction with or .
Watch files for changes, rerunning the specified command when any file is updated.
Instead of writing out the JavaScript as a file, print it directly to stdout.
Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT. Good for use with processes written in other languages. An example:
Parses the code as Literate CoffeeScript. You only need to specify this when passing in code directly over stdio, or using some sort of extension-less file name.
Compile and print a little snippet of CoffeeScript directly from the command line. For example:
the given module before starting the REPL or evaluating the code given with the flag.
Compile the JavaScript without the top-level function safety wrapper.
Suppress the “Generated by CoffeeScript” header.
The executable has some useful options you can set, such as , , , and . Use this flag to forward options directly to Node.js. To pass multiple flags, use multiple times.
Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler.
Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree. Used for debugging the compiler.

Examples:

  • Compile a directory tree of files in into a parallel tree of files in :
  • Watch a file for changes, and recompile it every time the file is saved:
  • Concatenate a list of files into a single script:
  • Print out the compiled JS from a one-liner:
  • All together now, watch and recompile an entire project as you work on it:
  • Start the CoffeeScript REPL ( to exit, for multi-line):

To use , see Transpilation.

Node.js

If you’d like to use Node.js’ CommonJS to CoffeeScript files, e.g. , you must first “register” CoffeeScript as an extension:

If you want to use the compiler’s API, for example to make an app that compiles strings of CoffeeScript on the fly, you can the full module:

The method has the signature where is a string of CoffeeScript code, and the optional is an object with some or all of the following properties:

  • , boolean: if true, a source map will be generated; and instead of returning a string, will return an object of the form .
  • , boolean: if true, output the source map as a base64-encoded string in a comment at the bottom.
  • , string: the filename to use for the source map. It can include a path (relative or absolute).
  • , boolean: if true, output without the top-level function safety wrapper.
  • , boolean: if true, output the header.
  • , object: if set, this must be an object with the options to pass to Babel. See Transpilation.

Transpilation

CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run might not support all of that syntax. In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, into . This is done via transpilers like Babel, Bublé or Traceur Compiler.

Quickstart

From the root of your project:

Transpiling with the CoffeeScript compiler

To make things easy, CoffeeScript has built-in support for the popular Babel transpiler. You can use it via the command-line option or the Node API option. To use either, must be installed in your project:

Or if you’re running the command outside of a project folder, using a globally-installed module, needs to be installed globally:

By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways, too.) A minimal file would be just . This implies that you have installed :

See Babel’s website to learn about presets and plugins and the multitude of options you have. Another preset you might need is if you’re using JSX with React (JSX can also be used with other frameworks).

Once you have and (or other presets or plugins) installed, and a file (or other equivalent) in place, you can use to pipe CoffeeScript’s output through Babel using the options you’ve saved.

If you’re using CoffeeScript via the Node API, where you call with a string to be compiled and an object, the key of the object should be the Babel options:

You can also transpile CoffeeScript’s output without using the option, for example as part of a build chain. This lets you use transpilers other than Babel, and it gives you greater control over the process. There are many great task runners for setting up JavaScript build chains, such as Gulp, Webpack, Grunt and Broccoli.

Polyfills

Note that transpiling doesn’t automatically supply polyfills for your code. CoffeeScript itself will output if you use the operator, or destructuring or spread/rest syntax; and if you use a bound () method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is , though there are many otherstrategies.

Language Reference

This reference is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right.

Many of the examples can be run (where it makes sense) by pressing thebutton on the right. The CoffeeScript on the left is editable, and the JavaScript will update as you edit.

First, the basics: CoffeeScript uses significant whitespace to delimit blocks of code. You don’t need to use semicolons to terminate expressions, ending the line will do just as well (although semicolons can still be used to fit multiple expressions onto a single line). Instead of using curly braces to surround blocks of code in functions, if-statements, switch, and try/catch, use indentation.

You don’t need to use parentheses to invoke a function if you’re passing arguments. The implicit call wraps forward to the end of the line or block expression.

Functions

Functions are defined by an optional list of parameters in parentheses, an arrow, and the function body. The empty function looks like this:

square=(x)->x*xcube=(x)->square(x)*x
varcube, square; square=function(x) { returnx*x; }; cube=function(x) { returnsquare(x) *x; };

Functions may also have default values for arguments, which will be used if the incoming argument is missing ().

fill=(container,liquid="coffee")->"Filling the #{container} with #{liquid}..."
varfill; fill=function(container, liquid="coffee") { return`Filling the ${container}with ${liquid}...`; };

Strings

Like JavaScript and many other languages, CoffeeScript supports strings as delimited by the or characters. CoffeeScript also supports string interpolation within -quoted strings, using . Single-quoted strings are literal. You may even use interpolation in object keys.

author="Wittgenstein"quote="A picture is a fact. -- #{ author }"sentence="#{ 22 / 7 } is a decent approximation of π"
varauthor, quote, sentence; author="Wittgenstein"; quote=`A picture is a fact. -- ${author}`; sentence=`${22/7}is a decent approximation of π`;

Multiline strings are allowed in CoffeeScript. Lines are joined by a single space unless they end with a backslash. Indentation is ignored.

mobyDick="Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."
varmobyDick; mobyDick="Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";

Block strings, delimited by or , can be used to hold formatted or indentation-sensitive text (or, if you just don’t feel like escaping quotes and apostrophes). The indentation level that begins the block is maintained throughout, so you can keep it all aligned with the body of your code.

html=""" <strong> cup of coffeescript </strong> """
varhtml; html="<strong>\n cup of coffeescript\n</strong>";

Double-quoted block strings, like other double-quoted strings, allow interpolation.

Objects and Arrays

The CoffeeScript literals for objects and arrays look very similar to their JavaScript cousins. When each property is listed on its own line, the commas are optional. Objects may be created using indentation instead of explicit braces, similar to YAML.

song=["do","re","mi","fa","so"]singers={Jagger:"Rock",Elvis:"Roll"}bitlist=[1,0,10,0,11,1,0]kids=brother:name:"Max"age:11sister:name:"Ida"age:9
varbitlist, kids, singers, song; song= ["do", "re", "mi", "fa", "so"]; singers= { Jagger: "Rock", Elvis: "Roll" }; bitlist= [1, 0, 1, 0, 0, 1, 1, 1, 0]; kids= { brother: { name: "Max", age: 11 }, sister: { name: "Ida", age: 9 } };

CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.

name="Michelangelo"mask="orange"weapon="nunchuks"turtle={name,mask,weapon}output="#{turtle.name} wears an #{turtle.mask} mask. Watch out for his #{turtle.weapon}!"
varmask, name, output, turtle, weapon; name="Michelangelo"; mask="orange"; weapon="nunchuks"; turtle= {name, mask, weapon}; output=`${turtle.name}wears an ${turtle.mask}mask. Watch out for his ${turtle.weapon}!`;

Lexical Scoping and Variable Safety

The CoffeeScript compiler takes care to make sure that all of your variables are properly declared within lexical scope — you never need to write yourself.

outer=1changeNumbers=->inner=-1outer=10inner=changeNumbers()
varchangeNumbers, inner, outer; outer=1; changeNumbers=function() { varinner; inner=-1; returnouter=10; }; inner=changeNumbers();

Notice how all of the variable declarations have been pushed up to the top of the closest scope, the first time they appear. is not redeclared within the inner function, because it’s already in scope; within the function, on the other hand, should not be able to change the value of the external variable of the same name, and therefore has a declaration of its own.

Because you don’t have direct access to the keyword, it’s impossible to shadow an outer variable on purpose, you may only refer to it. So be careful that you’re not reusing the name of an external variable accidentally, if you’re writing a deeply nested function.

Although suppressed within this documentation for clarity, all CoffeeScript output (except in files with or statements) is wrapped in an anonymous function: . This safety wrapper, combined with the automatic generation of the keyword, make it exceedingly difficult to pollute the global namespace by accident. (The safety wrapper can be disabled with the option, and is unnecessary and automatically disabled when using modules.)

If you’d like to create top-level variables for other scripts to use, attach them as properties on ; attach them as properties on the object in CommonJS; or use an statement. If you’re targeting both CommonJS and the browser, the existential operator (covered below), gives you a reliable way to figure out where to add them: .

Since CoffeeScript takes care of all variable declaration, it is not possible to declare variables with ES2015’s or . This is intentional; we feel that the simplicity gained by not having to think about variable declaration outweighs the benefit of having three separate ways to declare variables.

If, Else, Unless, and Conditional Assignment

/ statements can be written without the use of parentheses and curly brackets. As with functions and other block expressions, multi-line conditionals are delimited by indentation. There’s also a handy postfix form, with the or at the end.

CoffeeScript can compile statements into JavaScript expressions, using the ternary operator when possible, and closure wrapping otherwise. There is no explicit ternary statement in CoffeeScript — you simply use a regular statement on a single line.

mood=greatlyImprovedifsingingifhappyandknowsItclapsHands()chaChaCha()elseshowIt()date=iffridaythensueelsejill
vardate, mood; if (singing) { mood=greatlyImproved; } if (happy&&knowsIt) { clapsHands(); chaChaCha(); } else { showIt(); } date=friday?sue : jill;

Splats, or Rest Parameters/Spread Syntax

The JavaScript object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides splats , both for function definition as well as invocation, making variable numbers of arguments a little bit more palatable. ES2015 adopted this feature as their rest parameters.

gold=silver=rest="unknown"awardMedals=(first,second,others...)->gold=firstsilver=secondrest=otherscontenders=["Michael Phelps""Liu Xiang""Yao Ming""Allyson Felix""Shawn Johnson""Roman Sebrle""Guo Jingjing""Tyson Gay""Asafa Powell""Usain Bolt"]awardMedalscontenders...alert"""Gold: #{gold}Silver: #{silver}The Field: #{rest.join ', '}"""
varawardMedals, contenders, gold, rest, silver; gold=silver=rest="unknown"; awardMedals=function(first, second, ...others) { gold=first; silver=second; returnrest=others; }; contenders= ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; awardMedals(...contenders); alert(`Gold: ${gold}\nSilver: ${silver}\nThe Field: ${rest.join(', ')}`);

Splats also let us elide array elements…

popular=['pepperoni','sausage','cheese']unwanted=['anchovies','olives']all=[popular...,unwanted...,'mushrooms']
varall, popular, unwanted; popular= ['pepperoni', 'sausage', 'cheese']; unwanted= ['anchovies', 'olives']; all= [...popular, ...unwanted, 'mushrooms'];

…and object properties.

user=name:'Werner Heisenberg'occupation:'theoretical physicist'currentUser={user...,status:'Uncertain'}
varcurrentUser, user, _extends=Object.assign||function (target) { for (vari=1; i<arguments.length; i++) { varsource=arguments[i]; for (varkeyinsource) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] =source[key]; } } } returntarget; }; user= { name: 'Werner Heisenberg', occupation: 'theoretical physicist' }; currentUser=_extends({}, user, { status: 'Uncertain' });

In ECMAScript this is called spread syntax, and has been supported for arrays since ES2015 but is coming soon for objects. Until object spread syntax is officially supported, the CoffeeScript compiler outputs the same polyfill as Babel’s rest spread transform; but once it is supported, we will revise the compiler’s output. Note that there are very subtle differences between the polyfill and the current proposal.

Loops and Comprehensions

Most of the loops you’ll write in CoffeeScript will be comprehensions over arrays, objects, and ranges. Comprehensions replace (and compile into) loops, with optional guard clauses and the value of the current array index. Unlike for loops, array comprehensions are expressions, and can be returned and assigned.

eat=(food)->"#{food} eaten."eatfoodforfoodin['toast','cheese','wine']courses=['greens','caviar','truffles','roast','cake']menu=(i,dish)->"Menu Item #{i}: #{dish}"menui+1,dishfordish,iincoursesfoods=['broccoli','spinach','chocolate']eatfoodforfoodinfoodswhenfoodisnt'chocolate'
varcourses, dish, eat, food, foods, i, j, k, l, len, len1, len2, menu, ref; eat=function(food) { return`${food}eaten.`; }; ref= ['toast', 'cheese', 'wine']; for (j=0, len=ref.length; j<len; j++) { food=ref[j

It seems to me this railscast is presenting the incorrect way to put content into javascript variables.

If you are trying to put a template variable into a javascript variable inside an HTML template, the syntax is actually not very intuitive:

You have to flag the string as safe for raw output into the html document, but also apply javascript escaping. Otherwise, if @foo contains "<foo>" then your final document output will be:

Which is almost certainly not what you want.

However, if you use html_safe but forget to apply the javascript escaping, you are opening yourself seriously to javascript injection attacks. So this is stuff that must be done very carefully in order to be done both correctly and safely.

IMO it is unfortunate that apparently no authoritative documentation or respected tutorials point this nuance out, and that Rails has no better, more intuitive way to put content safely and correctly into javascript strings...

0 thoughts on “Coffeescript If Else Assignment Of Rents”

    -->

Leave a Comment

Your email address will not be published. Required fields are marked *