diff options
author | isaacs <i@izs.me> | 2010-05-09 16:35:15 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-05-29 12:31:46 -0700 |
commit | 3c7873bd3f7b823db07f08e55fdeac5e4fbde3e9 (patch) | |
tree | 3fd001c9862e0f169ba1c4f43e16f2052f745808 | |
parent | 2fa4de001c12d9524b7380930c58e64db14d8998 (diff) | |
download | nodejs-3c7873bd3f7b823db07f08e55fdeac5e4fbde3e9.tar.gz nodejs-3c7873bd3f7b823db07f08e55fdeac5e4fbde3e9.tar.bz2 nodejs-3c7873bd3f7b823db07f08e55fdeac5e4fbde3e9.zip |
Use duck-typing as well as instanceof in sys.inspect
This makes it so that inspecting objects from other contexts works as expected.
-rw-r--r-- | lib/sys.js | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/sys.js b/lib/sys.js index 28ec6ff74..3dfcdee77 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -65,7 +65,7 @@ exports.inspect = function (obj, showHidden, depth) { // Functions without properties can be shortcutted. if (typeof value === 'function' && keys.length === 0) { - if (value instanceof RegExp) { + if (isRegExp(value)) { return '' + value; } else { return '[Function]'; @@ -73,13 +73,13 @@ exports.inspect = function (obj, showHidden, depth) { } // Dates without properties can be shortcutted - if (value instanceof Date && keys.length === 0) { + if (isDate(value) && keys.length === 0) { return value.toUTCString(); } var base, type, braces; // Determine the object type - if (value instanceof Array) { + if (isArray(value)) { type = 'Array'; braces = ["[", "]"]; } else { @@ -89,13 +89,13 @@ exports.inspect = function (obj, showHidden, depth) { // Make functions say that they are functions if (typeof value === 'function') { - base = (value instanceof RegExp) ? ' ' + value : ' [Function]'; + base = (isRegExp(value)) ? ' ' + value : ' [Function]'; } else { base = ""; } // Make dates with properties first say the date - if (value instanceof Date) { + if (isDate(value)) { base = ' ' + value.toUTCString(); } @@ -106,7 +106,7 @@ exports.inspect = function (obj, showHidden, depth) { } if (recurseTimes < 0) { - if (value instanceof RegExp) { + if (isRegExp(value)) { return '' + value; } else { return "[Object]"; @@ -140,7 +140,7 @@ exports.inspect = function (obj, showHidden, depth) { str = format(value[key], recurseTimes - 1); } if (str.indexOf('\n') > -1) { - if (value instanceof Array) { + if (isArray(value)) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); @@ -191,6 +191,29 @@ exports.inspect = function (obj, showHidden, depth) { } return format(obj, (typeof depth === 'undefined' ? 2 : depth)); }; +function isArray (ar) { + return ar instanceof Array + || Array.isArray(ar) + || (ar && ar !== Object.prototype && isArray(ar.__proto__)); +} +function isRegExp (re) { + var s = ""+re; + return re instanceof RegExp // easy case + || typeof(re) === "function" // duck-type for context-switching evalcx case + && re.constructor.name === "RegExp" + && re.compile + && re.test + && re.exec + && s.charAt(0) === "/" + && s.substr(-1) === "/"; +} +function isDate (d) { + if (d instanceof Date) return true; + if (typeof d !== "object") return false; + var properties = Date.prototype && Object.getOwnPropertyNames(Date.prototype); + var proto = d.__proto__ && Object.getOwnPropertyNames(d.__proto__); + return JSON.stringify(proto) === JSON.stringify(properties); +} var pWarning; |