summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2010-05-09 16:35:15 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-05-29 12:31:46 -0700
commit3c7873bd3f7b823db07f08e55fdeac5e4fbde3e9 (patch)
tree3fd001c9862e0f169ba1c4f43e16f2052f745808
parent2fa4de001c12d9524b7380930c58e64db14d8998 (diff)
downloadnodejs-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.js37
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;