Kaffeine uses a plugin style approach, with a core/standard stack (order is important)
This is an example taken from production code. It show most of Kaffeine's features:
Edge::add = (nick, name, complete, opts) { opts ||= {} @client.select 15 user = User.find! {id: nick} puzzle = Puzzle.find! {name: name} err, data = client.set! "u:#{user}:p:#{puzzle}" complete() }
Allows function calls with callbacks to be unwrapped via a ! postfix. E.g:
fish = $.get!('/fish') $("stomach").append(fish) ok = stomach.save!() meal.complete = ok
Provide the @ alias for 'this'. E.g:
@legs = legs @color = color
In the case of an unwrapped function, @ will be rewritten to refer to the original this, for convenience. Use this
to refer to the actuak this
Fish.prototype.eat = { @food = getFood!() @stomach.ingest! @food poop = @stomach.digest! @food this.next(poop) }
provides support for omitting the var keyword: the variables will be automagically defined in the closest relevant closure. E.g.
x = null { x = 1 y = 2 }
Provide optional brackets for function calls. E.g.
remove eggs.shell mix eggs, milk.off ? milk : null outer inner innermost
Allows for multiline strings:
var html = " <body> <h1>SOY SAUCE</h1> </body> "
Maintains new lines --- but can be suppressed with the \ character (which provides parity with normal javascript):
var html = "\ <body>\ <h1>SOY SAUCE</h1>\ </body>\ "
Allows an 'of' operator for looping through arrays:
for(x of [7,3,4]) sum += x
An optional second parameter will refer to the key:
for(x, i of [7,3,4]) sum += i
Also allows an optional second parameter for the in
keyword:
for(key, val in A) zip += "#key:#val"
provides ruby style string interpolation via #{}
letter = "Dear #{name}, I am writing to you to inform you of #{purpose} Kind Regards #{sender} "
the last statement of a function will be automagically returned. E.g.
getName = { @name }
This will only work for variables, objects and functions. I.e. an final if statement will result no return value
provides the # shortcut for referring to the first argument in a function. Additionally, #n refers to the nth argument (n >= 0). Useful for terse function definitions, e.g:
square = { #*# } times = { #*#1 }
the function keyword can be optionally omitted, along with empty argument lists.
ok = (timeout) { sendNote() setTimeout { run() }, timeout return true }
Note {} could be a function or an object, so to avoid ambiguity, it's defined to be an object. To express an empty function, use one of the following forms:
{;} {null} function() { }
Provides an alternative calling method than can be used for easily chaining (UNIX style passing).
result = input | fn args
Chaining input to output:
result = input | fn a, b | fn2 c | fn3 d
For example, it is very useful for ruby style enumeration chaining without using prototypes, and other utilities
| = require "pipe_utils" People | map { #.name } | detect { #.length > 3 } opts = opts | extend default 5 | times { if(!send()) return false } names | asyncMap (name, fn) { user = User.find! {name: name} fn(user) }, complete
2 extra assignment operators, ||=
and .=
location.href .= replace("?old", "?new") name .= toUpperCase() opts ||= {}
npm install kaffeine