Comparing version 0.2.2 to 0.2.3
@@ -8,2 +8,31 @@ # Documentation | ||
- [Objects](objects) | ||
- [Strings](strings) | ||
- [Strings](strings) | ||
## Lingo | ||
Throughout the documentation, tests, and source code, methods are referred to as *minor* and *major*. *'What does this mean?',* you ask. Well, if you would kindly stop interrupting me, I'll tell you. | ||
Hmm. | ||
*Major* methods are the same old functions-assigned-to-properties that we're all used to. They're basic functions attached to the prototype chain. They accept arguments, and they can chain `.call`, `.apply`, `.bind`, because they *are* functions. | ||
*Minor* methods are methods implemented behind *getters* & *setters*. It would be fair to simply call them getters, but there's generally a lot more going on below the surface than just property retrieval. They can *not* be invoked externally, and as such they never accept any arguments. The are simply called. | ||
## Immutable . . . or ? | ||
No! Yes. Maybe? Kind of. Mostly no, actually! | ||
Major methods are fair game to all types of changes - instanced and prototype. | ||
On prototypes, minor methods can be overridden with assignment, redefined with `Object.defineProperty`, or removed with the `delete` operator. | ||
Minor methods can be overridden on *instances*, but only on **Objects**, **Functions**, and **Arrays**. Booleans, Numbers, and Strings will fail loudly, because `Object.defineProperty` will be called with the non-object as the `this` context. The `delete` operator will not work either. | ||
## Sanity check, please! | ||
If a method, minor or major, already exists on a prototype it will not be overridden. | ||
One can safely include Rubyisms at just about any time, and be fairly certain of no conflicts. | ||
{ | ||
"name": "rubyisms", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "Prototype extensions.", | ||
@@ -5,0 +5,0 @@ "main": "rubyisms.js", |
@@ -11,2 +11,4 @@ <p align="center"> | ||
[![NPM version][npm-image]][npm-url] [![Downloads][npm-downloads]][npm-url] [![Build Status][travis-build]][travis-url] | ||
## Info | ||
@@ -18,60 +20,15 @@ | ||
Using [npm](https://www.npmjs.com/). | ||
Using [npm](https://www.npmjs.com/), of course. | ||
npm install rubyisms | ||
$ npm install rubyisms | ||
## Documentation | ||
~~Full~~ list of methods [here](https://github.com/Oka-/rubyisms/tree/master/docs). | ||
Full list of methods [here](https://github.com/Oka-/rubyisms/tree/master/docs). | ||
## Issues | ||
[npm-url]: https://www.npmjs.com/package/rubyisms | ||
[npm-image]: http://img.shields.io/npm/v/rubyisms.svg | ||
[npm-downloads]: http://img.shields.io/npm/dm/rubyisms.svg | ||
### `Object.prototype` | ||
Rubyisms defines properties on `Object.prototype`. A side effect is the creation of globally scoped *constants*. The following should be treated as reserved keywords in the global scope, and are not writable. | ||
- `array` | ||
- `bool` | ||
- `func` | ||
- `numeric` | ||
- `object` | ||
- `size` | ||
- `type` | ||
*Everything* created will contain these as prototype properties. To override these properties on objects you must define them during construction, or explicitly define them with `Object.defineProperty`. | ||
No good. | ||
```JavaScript | ||
var o = {}; | ||
o.size = 5 // Will not write | ||
o.size // 0 | ||
function Constructor () { | ||
this.size = 5; // Will not write | ||
} | ||
new Constructor().size // 0 | ||
``` | ||
Better. | ||
```JavaScript | ||
var o = {size: 5}; | ||
o.size // 5 | ||
function Constructor () { | ||
Object.defineProperty(this, 'size', { | ||
value: 5, | ||
writable: true | ||
}); | ||
} | ||
new Constructor().size // 5 | ||
``` | ||
### `.type` | ||
Return values from calling `.type` on the global object will differ. In V8 (Chrome, Node), the return string is `'global'`, whereas in other browsers it is `'window'`. | ||
[travis-url]: https://travis-ci.org/Oka-/rubyisms | ||
[travis-build]: https://travis-ci.org/Oka-/rubyisms.svg?branch=master |
261
rubyisms.js
// Colin 'Oka' Hall-Coates | ||
// http://oka.io | ||
// http://oka.io <yo@oka.io> | ||
// MIT, 2015 | ||
;(function ($) { | ||
;(function (G) { | ||
'use strict'; | ||
var def = Object.defineProperties, | ||
AP = Array.prototype, | ||
BP = Boolean.prototype, | ||
FP = Function.prototype, | ||
NP = Number.prototype, | ||
OP = Object.prototype, | ||
SP = String.prototype; | ||
function define(s, v) { | ||
var type = Object.prototype.toString.call(this), | ||
isObject = (type === '[object Object]'); | ||
function $(g, s) {return {get: g, set: s};} | ||
delete this[s]; | ||
Object.defineProperty(this, s, { | ||
value: v, | ||
writable: true, | ||
enumerable: isObject, | ||
configurable: true | ||
}); | ||
} | ||
// Minor methods | ||
function strap(g, s) { | ||
return {get: g, set: function (v) { | ||
define.call(this, s, v); | ||
}, configurable: true}; | ||
} | ||
def(AP, { | ||
clear: $(function () { | ||
function minor(prototype, o) { | ||
for (var k in o) { | ||
if (o.hasOwnProperty(k) && !prototype.hasOwnProperty(k)) { | ||
Object.defineProperty(prototype, k, strap(o[k], k)); | ||
} | ||
} | ||
} | ||
function major(prototype, o) { | ||
for (var k in o) { | ||
if (!prototype.hasOwnProperty(k)) { | ||
Object.defineProperty(prototype, k, { | ||
value: o[k], | ||
writable: true, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
} | ||
minor(Array.prototype, { | ||
clear: function () { | ||
while (this.length > 0) this.pop(); return this; | ||
}), | ||
compact: $(function () { | ||
}, | ||
compact: function () { | ||
return this.filter(function (e) { | ||
return (typeof e !== 'undefined'); | ||
}); | ||
}), | ||
sample: $(function () { | ||
}, | ||
sample: function () { | ||
return this[Math.floor(Math.random() * this.length)]; | ||
}), | ||
uniq: $(function () { | ||
}, | ||
uniq: function () { | ||
var c = {}; | ||
@@ -38,68 +64,68 @@ return this.filter(function (e) { | ||
}); | ||
}), | ||
} | ||
}); | ||
def(BP, { | ||
not: $(function () { | ||
minor(Boolean.prototype, { | ||
not: function () { | ||
return !this; | ||
}) | ||
} | ||
}); | ||
def(FP, {}); | ||
minor(Function.prototype, {}); | ||
def(NP, { | ||
abs: $(function () { | ||
minor(Number.prototype, { | ||
abs: function () { | ||
return Math.abs(this); | ||
}), | ||
abs2: $(function () { | ||
}, | ||
abs2: function () { | ||
return this * this; | ||
}), | ||
arg: $(function () { | ||
}, | ||
arg: function () { | ||
return (this < 0 ? Math.PI : 0); | ||
}), | ||
ceil: $(function () { | ||
}, | ||
ceil: function () { | ||
return Math.ceil(this); | ||
}), | ||
finite: $(function () { | ||
}, | ||
finite: function () { | ||
return isFinite(this); | ||
}), | ||
floor: $(function () { | ||
}, | ||
floor: function () { | ||
return Math.floor(this); | ||
}), | ||
integer: $(function () { | ||
}, | ||
integer: function () { | ||
return this.toFixed() == this && this !== Infinity; | ||
}), | ||
nonzero: $(function () { | ||
}, | ||
nonzero: function () { | ||
return (this !== 0 ? this: null); | ||
}), | ||
polar: $(function () { | ||
}, | ||
polar: function () { | ||
return (isFinite(this) && | ||
[Math.abs(this), (this < 0 ? Math.PI : 0)]) || | ||
undefined; | ||
}), | ||
round: $(function () { | ||
}, | ||
round: function () { | ||
return Math.round(this); | ||
}), | ||
zero: $(function () { | ||
}, | ||
zero: function () { | ||
return this === 0; | ||
}) | ||
} | ||
}); | ||
def(OP, { | ||
array: $(function () { | ||
return OP.toString.call(this) === '[object Array]'; | ||
}), | ||
bool: $(function () { | ||
return OP.toString.call(this) === '[object Boolean]'; | ||
}), | ||
func: $(function () { | ||
return OP.toString.call(this) === '[object Function]'; | ||
}), | ||
numeric: $(function () { | ||
return OP.toString.call(this) === '[object Number]' && this === this; | ||
}), | ||
object: $(function () { | ||
return OP.toString.call(this) === '[object Object]'; | ||
}), | ||
size: $(function () { | ||
minor(Object.prototype, { | ||
array: function () { | ||
return Object.prototype.toString.call(this) === '[object Array]'; | ||
}, | ||
bool: function () { | ||
return Object.prototype.toString.call(this) === '[object Boolean]'; | ||
}, | ||
func: function () { | ||
return Object.prototype.toString.call(this) === '[object Function]'; | ||
}, | ||
numeric: function () { | ||
return Object.prototype.toString.call(this) === '[object Number]' && this === this; | ||
}, | ||
object: function () { | ||
return Object.prototype.toString.call(this) === '[object Object]'; | ||
}, | ||
size: function () { | ||
if (Array.isArray(this) || | ||
@@ -110,37 +136,37 @@ typeof this === 'string' || | ||
else if (typeof this === 'number' && this === this) return this; | ||
}), | ||
string: $(function () { | ||
return OP.toString.call(this) === '[object String]'; | ||
}), | ||
type: $(function () { | ||
var t = OP.toString.call(this).match(/\w+(?=\])/)[0].toLowerCase(); | ||
}, | ||
string: function () { | ||
return Object.prototype.toString.call(this) === '[object String]'; | ||
}, | ||
type: function () { | ||
var t = Object.prototype.toString.call(this).match(/\w+(?=\])/)[0].toLowerCase(); | ||
return (t === 'number' && this !== this ? 'NaN' : t); | ||
}) | ||
} | ||
}); | ||
def(SP, { | ||
capitalize: $(function () { | ||
minor(String.prototype, { | ||
capitalize: function () { | ||
return this.substring(0, 1).toUpperCase() + this.substring(1); | ||
}), | ||
chars: $(function () { | ||
}, | ||
chars: function () { | ||
return this.split(''); | ||
}), | ||
chop: $(function () { | ||
}, | ||
chop: function () { | ||
return this.slice(0, this.length - 1); | ||
}), | ||
chr: $(function () { | ||
}, | ||
chr: function () { | ||
return this.substring(0, 1); | ||
}), | ||
downcase: $(function () { | ||
}, | ||
downcase: function () { | ||
return this.toLowerCase(); | ||
}), | ||
empty: $(function () { | ||
}, | ||
empty: function () { | ||
return this.length < 1; | ||
}), | ||
reverse: $(function () { | ||
}, | ||
reverse: function () { | ||
var r = '', i = this.length - 1, e; | ||
for (e = 0; i >= e; i--) r += this[i]; | ||
return r; | ||
}), | ||
swapcase: $(function () { | ||
}, | ||
swapcase: function () { | ||
var s = '', i, c; | ||
@@ -153,19 +179,16 @@ for (i = 0; i < this.length; i++) { | ||
return s; | ||
}), | ||
upcase: $(function () { | ||
}, | ||
upcase: function () { | ||
return this.toUpperCase(); | ||
}) | ||
} | ||
}); | ||
// Major methods | ||
var _Array = { | ||
_p: AP, | ||
major(Array.prototype, { | ||
assoc: function (key) { | ||
for (var i = 0; i < this.length; i++) { | ||
if (OP.toString.call(this[i]) !== '[object Object]') continue; | ||
if (Object.prototype.toString.call(this[i]) !== '[object Object]') continue; | ||
if (this[i].hasOwnProperty(key)) return this[i]; | ||
} | ||
}, | ||
drop: AP.slice, | ||
drop: Array.prototype.slice, | ||
fetch: function(n, d) { | ||
@@ -184,3 +207,3 @@ if (typeof n !== 'number' || !isFinite(n)) throw new TypeError('Expected number'); | ||
}, | ||
select: AP.filter, | ||
select: Array.prototype.filter, | ||
take: function (n) { | ||
@@ -219,39 +242,31 @@ return this.slice().splice(0, n); | ||
} | ||
}; | ||
}); | ||
var _Boolean = { | ||
_p: BP | ||
}; | ||
major(Boolean.prototype, {}); | ||
var _Function = { | ||
_p: FP | ||
}; | ||
major(Function.prototype, {}); | ||
var _Number = { | ||
_p: NP | ||
}; | ||
major(Number.prototype, {}); | ||
var _Object = { | ||
_p: OP, | ||
major(Object.prototype, { | ||
eql: function (o) { | ||
return this === o; | ||
} | ||
}; | ||
}); | ||
var _String = { | ||
_p: SP, | ||
major(String.prototype, { | ||
prepend: function (o) { | ||
return o + this; | ||
} | ||
}; | ||
}); | ||
function buildPrototypes(e) { | ||
for (var k in e) { | ||
if (k === '_p') continue; | ||
if (e.hasOwnProperty(k)) e._p[k] = (e._p[k] || e[k]); | ||
} | ||
} | ||
// Unset | ||
G.array = undefined; | ||
G.bool = undefined; | ||
G.func = undefined; | ||
G.numeric = undefined; | ||
G.size = undefined; | ||
G.string = undefined; | ||
G.type = undefined; | ||
[_Array, _Boolean, _Function, _Number, _Object, _String].forEach(buildPrototypes); | ||
}()); | ||
}((typeof window !== 'undefined' ? window : global))); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
82628
21
746
32