Skip to content

Instantly share code, notes, and snippets.

@stoeffel
Created March 8, 2015 09:27
Show Gist options
  • Select an option

  • Save stoeffel/a68e4a54c29e9c2e04a0 to your computer and use it in GitHub Desktop.

Select an option

Save stoeffel/a68e4a54c29e9c2e04a0 to your computer and use it in GitHub Desktop.
requirebin sketch
// require() some stuff from npm (like you were using browserify)
// and then hit Rebuild to run it on the right
var get = require('101/pluck');
var set = require('101/set');
var lense = function(key) {
var l = get(key);
l.set = set(key);
l.mod = function(mod, obj) {
return l.set(mod(l(obj)));
};
};
var obj = {a:2, b:3};
var l= lense('a');
alert(l(obj));
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=assign;function assign(target,firstSource){if(arguments.length===1){firstSource=arguments[0];return function(target){return assign(target,firstSource)}}if(target===undefined||target===null)throw new TypeError("Cannot convert first argument to object");var to=Object(target);for(var i=1;i<arguments.length;i++){var nextSource=arguments[i];if(nextSource===undefined||nextSource===null)continue;var keysArray=Object.keys(Object(nextSource));for(var nextIndex=0,len=keysArray.length;nextIndex<len;nextIndex++){var nextKey=keysArray[nextIndex];Object.getOwnPropertyDescriptor(nextSource,nextKey);to[nextKey]=nextSource[nextKey]}}return to}},{}],2:[function(require,module,exports){module.exports=exists;function exists(val){return val!==undefined&&val!==null}},{}],3:[function(require,module,exports){var exists=require("./exists");module.exports=isObject;function isObject(val){return typeof val==="object"&&exists(val)&&!Array.isArray(val)&&!(val instanceof RegExp)&&!(val instanceof String)&&!(val instanceof Number)}},{"./exists":2}],4:[function(require,module,exports){module.exports=isString;function isString(val){return typeof val==="string"||val instanceof String}},{}],"101/set":[function(require,module,exports){var assign=require("./assign");var isString=require("./is-string");var isObject=require("./is-object");module.exports=set;function set(obj,key,val){var setObj;if(arguments.length===1){setObj=obj;return function(obj){return assign(obj,setObj)}}if(arguments.length===2){if(isString(obj)||typeof obj==="number"){val=key;key=obj;setObj={};setObj[key]=val;return function(obj){return assign(obj,setObj)}}else if(isObject(key)){setObj=key;return assign(obj,setObj)}else{throw new TypeError("Invalid arguments: expected str, val or val, obj")}}else{setObj={};setObj[key]=val;return assign(obj,setObj)}}},{"./assign":1,"./is-object":3,"./is-string":4}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=exists;function exists(val){return val!==undefined&&val!==null}},{}],2:[function(require,module,exports){var exists=require("./exists");module.exports=isObject;function isObject(val){return typeof val==="object"&&exists(val)&&!Array.isArray(val)&&!(val instanceof RegExp)&&!(val instanceof String)&&!(val instanceof Number)}},{"./exists":1}],3:[function(require,module,exports){(function(global){var keypather=module.exports=function(opts){var keypather=new Keypather(opts&&opts.force);return keypather};function Keypather(force){this.force=force!==undefined?Boolean(force):true}Keypather.prototype.get=function(){this.create=false;return this._get.apply(this,arguments)};Keypather.prototype._get=function(obj,keypath){this.obj=obj;keypath=keypath+"";this.keypathSplit=this.splitKeypath(keypath);this.fnArgs=Array.prototype.slice.call(arguments,2).map(makeArray);return this.keypathSplit.reduce(this.getValue.bind(this),obj)};Keypather.prototype.set=function(obj,keypath,value){this.obj=obj;keypath=keypath+"";this.create=this.force;this.fnArgs=Array.prototype.slice.call(arguments,3).map(makeArray);if(keypath.match(/\(\)$/)){throw new Error("Invalid left-hand side in assignment")}this.keypathSplit=this.splitKeypath(keypath);var lastKey=this.getLastKey();var val=this.getLastObj(arguments,true);val[lastKey]=value;return value};Keypather.prototype.in=function(obj,keypath){this.obj=obj;keypath=keypath+"";this.create=false;if(last(keypath)===")"){throw new TypeError("keypath should not end in a function")}this.keypathSplit=this.splitKeypath(keypath);var lastKey=this.getLastKey();var val=this.getLastObj(arguments);if(this.force&&!val){return false}return lastKey in val};Keypather.prototype.has=function(obj,keypath){this.obj=obj;keypath=keypath+"";this.create=false;if(last(keypath)===")"){throw new TypeError("keypath should not end in a function")}this.keypathSplit=this.splitKeypath(keypath);var lastKey=this.getLastKey();var val=this.getLastObj(arguments);if(this.force&&!val){return false}return val.hasOwnProperty(lastKey)};Keypather.prototype.del=function(obj,keypath){this.obj=obj;keypath=keypath+"";this.create=false;if(last(keypath)===")"){return true}this.keypathSplit=this.splitKeypath(keypath);this.fnArgs=Array.prototype.slice.call(arguments,2).map(makeArray);var lastKey=this.getLastKey();var val=this.getLastObj(arguments);if(this.force&&!val){return true}delete val[lastKey];return true};Keypather.prototype.splitKeypath=function(keypath){var dotSplit=keypath.split(".");var split=[];var openParen=false;var openBracket=false;var parenBuffer,bracketBuffer,preParen,preBracket;dotSplit.forEach(function groupParens(part){var parenSplit,leftover,bracketSplit;if(part.length===0){return}else if(!openParen&&~part.indexOf("(")){openParen=true;parenBuffer=[];parenSplit=part.split("(");preParen=parenSplit.shift()||"";leftover=parenSplit.join("(");if(leftover.length)groupParens(leftover)}else if(openParen){if(~part.indexOf(")")){openParen=false;parenSplit=part.split(")");parenBuffer.push(parenSplit.shift());split.push(preParen+"("+parenBuffer.join(".")+")");leftover=parenSplit.join(")");if(leftover.length)groupParens(leftover)}else{parenBuffer.push(part)}}else if(!openBracket&&~part.indexOf("[")){openBracket=true;bracketBuffer=[];bracketSplit=part.split("[");preBracket=bracketSplit.shift()||"";leftover=bracketSplit.join("[");if(leftover.length)groupParens(leftover)}else if(openBracket){if(~part.indexOf("]")){openBracket=false;bracketSplit=part.split("]");bracketBuffer.push(bracketSplit.shift());split.push(preBracket+"["+bracketBuffer.join(".")+"]");leftover=bracketSplit.join("]");if(leftover.length)groupParens(leftover)}else{bracketBuffer.push(part)}}else{split.push(part)}});return split};Keypather.prototype.getValue=function(val,keyPart){this.indexOpenParen=keyPart.indexOf("(");this.indexCloseParen=keyPart.indexOf(")");this.indexOpenBracket=keyPart.indexOf("[");this.indexCloseBracket=keyPart.indexOf("]");var keyHasParens=~this.indexOpenParen&&~this.indexCloseParen&&this.indexOpenParen<this.indexCloseParen;var keyHasBrackets=~this.indexOpenBracket&&~this.indexCloseBracket&&this.indexOpenBracket<this.indexCloseBracket;this.lastVal=val;if(!keyHasParens&&!keyHasBrackets){return this.handleKey(val,keyPart)}else if(keyHasParens&&(!keyHasBrackets||this.indexOpenParen<this.indexOpenBracket)){return this.handleFunction(val,keyPart)}else{return this.handleBrackets(val,keyPart)}};Keypather.prototype.handleKey=function(val,key){if(this.create&&!exists(val[key])){return this.createPath(val,key)}return this.force&&!exists(val)?null:val[key]};Keypather.prototype.handleFunction=function(val,keyPart){var subKey=keyPart.slice(0,this.indexOpenParen),ctx;var argsStr=keyPart.slice(this.indexOpenParen+1,this.indexCloseParen);if(subKey){if(this.create&&!exists(val[subKey])){throw new Error("KeypathSetError: cannot force create a path where a function does not exist")}ctx=val;val=this.force&&(!exists(val)||!exists(val[subKey]))?null:this.indexOpenParen+1===this.indexCloseParen?val[subKey].call(ctx):val[subKey].apply(ctx,this.parseFunctionArgs(argsStr))}else{ctx=this.lastVal||global;val=this.force&&!exists(val)?null:this.indexOpenParen+1===this.indexCloseParen?val.call(ctx):val.apply(ctx,this.parseFunctionArgs(argsStr))}keyPart=keyPart.slice(this.indexCloseParen+1);return keyPart?this.getValue(val,keyPart):val};Keypather.prototype.handleBrackets=function(val,keyPart){var subKey=keyPart.slice(0,this.indexOpenBracket);var bracketKey=keyPart.slice(this.indexOpenBracket+1,this.indexCloseBracket);bracketKey=parseBracketKey(bracketKey);if(!exists(bracketKey)){return this.handleKey(val,keyPart)}else{if(subKey){if(this.create){if(!exists(val[subKey])){return this.createPath(val,subKey,bracketKey)}if(!exists(val[subKey][bracketKey])){return this.createPath(val[subKey],bracketKey)}}val=this.force&&(!exists(val)||!exists(val[subKey]))?null:val[subKey][bracketKey]}else{if(this.create&&!exists(val[bracketKey])){return this.createPath(val,bracketKey)}val=this.force&&!exists(val)?null:val[bracketKey]}keyPart=keyPart.slice(this.indexCloseBracket+1);return keyPart?this.getValue(val,keyPart):val}};Keypather.prototype.getLastKey=function(){var lastKeyPart=this.keypathSplit.pop();var indexOpenBracket=lastKeyPart.lastIndexOf("[");var indexCloseBracket=lastKeyPart.lastIndexOf("]");var keyHasBrackets=~indexOpenBracket&&~indexCloseBracket&&indexOpenBracket<indexCloseBracket;if(keyHasBrackets){var bracketKey=lastKeyPart.slice(indexOpenBracket+1,indexCloseBracket);bracketKey=parseBracketKey(bracketKey);lastKeyPart=lastKeyPart.slice(0,indexOpenBracket);this.keypathSplit.push(lastKeyPart);return bracketKey}else{return lastKeyPart}};Keypather.prototype.getLastObj=function(args,setOperation){var val;if(this.keypathSplit.length===0){val=args[0]}else{var getArgs=Array.prototype.slice.call(args);getArgs[1]=this.keypathSplit.join(".");val=setOperation?this._get.apply(this,getArgs):this.get.apply(this,getArgs)}return val};Keypather.prototype.createPath=function(val){var keys=Array.prototype.slice.call(arguments,1);return keys.reduce(function(val,key,i){if(typeof keys[i+1]==="number"){val[key]=[]}else{val[key]={}}return val[key]},val)};Keypather.prototype.parseFunctionArgs=function(argsStr){argsStr=argsStr.trim();if(argsStr.length===0){return[]}else if(argsStr==="%"){return this.fnArgs.pop()||[]}var argsSplit=argsStr.split(",").map(trim);var replacementArgs;var self=this;return argsSplit.map(function(arg){if(arg==="%"){replacementArgs=replacementArgs||self.fnArgs.pop()||[];arg=replacementArgs.pop();return arg}else{var parsed=parseBracketKey(arg);parsed=exists(parsed)?parsed:keypather().get(self.obj,arg);if(exists(parsed)){return parsed}else{throw new ReferenceError('KeypatherError: Invalid function argument "'+arg+'"')}}})};function parseBracketKey(key){key=key.replace(/'/g,'"');try{return JSON.parse(key)}catch(err){return}}function exists(val){return val!==null&&val!==undefined}function last(arrOrStr){return arrOrStr[arrOrStr.length-1]}function makeArray(val){return Array.isArray(val)?val:[val]}function trim(str){return str.trim()}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],"101/pluck":[function(require,module,exports){var isObject=require("./is-object");var exists=require("./exists");var keypather=require("keypather")();module.exports=function(obj,key,isKeypath){if(!isObject(obj)){isKeypath=key;key=obj;return function(obj){return pluck(obj,key,isKeypath)}}else{return pluck(obj,key,isKeypath)}};function pluck(obj,key,isKeypath){key=Array.isArray(key)?key[0]:key;isKeypath=exists(isKeypath)?isKeypath:true;return isKeypath?keypather.get(obj,key):obj[key]}},{"./exists":1,"./is-object":2,keypather:3}]},{},[]);var get=require("101/pluck");var set=require("101/set");var lense=function(key){var l=get(key);l.set=set(key);l.mod=function(mod,obj){return l.set(mod(l(obj)))}};var obj={a:2,b:3};var l=lense("a");alert(l(obj));
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"101": "0.13.0"
}
}
<style type='text/css'>html, body { margin: 0; padding: 0; border: 0; }
body, html { height: 100%; width: 100%; }</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment