Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created May 24, 2012 20:25
Show Gist options
  • Select an option

  • Save cowboy/2784002 to your computer and use it in GitHub Desktop.

Select an option

Save cowboy/2784002 to your computer and use it in GitHub Desktop.
A modern JavaScript if-elseif-else abstraction, because control flow statements are so 1995
/*
* Abstraction.js
*
* Copyright (c) 2012 "Cowboy" Ben Alman
* Licensed under the MIT license.
* http://benalman.com/about/license/
*/
var Abstraction = (function($) {
var _ = $.prototype;
_.then = function(_) {
this._[0] && !this._.slice(1).some(Boolean) && _();
return this;
};
_.if = _.$if = function(_) {
this._ = [_];
return this.then;
};
_.elseif = _.$elseif = function(_) {
this._.unshift(_);
return this.then;
};
_.else = _.$else = function(_) {
this._.some(Boolean) || _();
return this;
};
return $;
}(function() {
this.then = this.then.bind(this);
this.then.then = this.then;
}));
// Working on the "chain" gang
(new Abstraction)
.if(true).then(function() {
console.log('log 1');
})
.if(false).then(function() {
console.log('no log');
})
.if(true).then(function() {
console.log('log 2');
})
.else(function() {
console.log('no log');
})
.if(false).then(function() {
console.log('no log');
})
.else(function() {
console.log('log 3');
})
.if(true).then(function() {
console.log('log 4');
})
.elseif(true).then(function() {
console.log('no log');
})
.else(function() {
console.log('no log');
})
// You actually don't even need the .then!
.if (false) (function() {
console.log('no log');
})
.elseif (true) (function() {
console.log('log 5');
})
.else (function() {
console.log('no log');
});
// For the sake of this example looking totally insane, this function returns the
// console.log function with all arguments pre-applied, to be called at a later time.
function console$log() {
return Function.bind.apply(console.log, [console].concat([].slice.call(arguments)));
}
// Dolla dolla "with" y'all (aka WTF)
with (new Abstraction) {
$if (true) (
console$log('log 1')
)
$if (false) (
console$log('no log')
)
$if (true) (
console$log('log 2')
)
$else (
console$log('no log')
)
$if (false) (
console$log('no log')
)
$else (
console$log('log 3')
)
$if (true) (
console$log('log 4')
)
$elseif (true) (
console$log('no log')
)
$else (
console$log('no log')
)
$if (false) (
console$log('no log')
)
$elseif (true) (
console$log('log 5')
)
$else (
console$log('no log')
)
}
@cowboy

cowboy commented May 24, 2012

Copy link
Copy Markdown
Author

(I've clearly put a lot of thought into this)

@polotek

polotek commented May 24, 2012

Copy link
Copy Markdown

Too verbose. This should really be supported by syntax.

@cowboy

cowboy commented May 24, 2012

Copy link
Copy Markdown
Author

I'm pushing for ES.prev, a return to ECMAScript basics.

@brianewing

Copy link
Copy Markdown

Reminds me of io, where control structures aren't special at all.

ghost commented May 24, 2012

Copy link
Copy Markdown

👍. This really needs to be a jQuery plugin, though.

@mkuklis

mkuklis commented May 24, 2012

Copy link
Copy Markdown

this looks awesome :)

@ryanflorence

Copy link
Copy Markdown

At least you get scoping! (also, you're crazy).

@cowboy

cowboy commented May 25, 2012

Copy link
Copy Markdown
Author

Yeah, now you can have "block" scope in JavaScript without those disgusting IIFEs!

@Javlopez

Copy link
Copy Markdown

i like this code!

@iros

iros commented May 25, 2012

Copy link
Copy Markdown

This form resembles traditional ifs more... ;)

@cowboy

cowboy commented May 25, 2012

Copy link
Copy Markdown
Author

I've actually added support for 2 different syntaxes. Chaining and WTF.

@buger

buger commented Aug 11, 2012

Copy link
Copy Markdown

Looks nice, but i'm afraid not usable with CoffeeScript.

@cowboy

cowboy commented Aug 31, 2012

Copy link
Copy Markdown
Author

Also see the other version, Abstraction.js "Lite".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment