Skip to content
This repository has been archived by the owner on Aug 19, 2021. It is now read-only.

Command: peek

johan edited this page Dec 7, 2010 · 2 revisions

h2. Usage

The peek command (and its helper family of aliases for some common RegExp filters) mimic repl.inspect, but sorting output a bit more orderly by type, and by default only lists direct properties of the object inspected. Pass a second numeric argument N to also list inherited properties to the N:th level, and/or a property name RegExp, and/or a property type RegExp, to list only the subset of key/values of the peeked object that match given criteria:

<pre> <code> repl> repl.peek(this); object ChromeWindow // this is the type of the object passed, here: "this" boolean: // first, all boolean properties and their values are listed, in alpha order: OPT_IN = true a11yEnabled = false gBidiUI = false gInPrintPreviewMode = false gIsLoadingBlank = false gMustLoadSidebar = false gPrintSettingsAreGlobal = false gSavePrintSettings = false function: // then all javascript functions (that you can inspect with fn.toSource()) $ // …​ native function: // next, all the native functions (whose function body is "{[native code]}") XPCNativeWrapper XPCSafeJSObjectWrapper addEventListener getInterface null: // as you see, types are also listed in alpha order gChromeState gClickAndHoldTimer gContextMenu gFocusedElement gPrevCharset gProgressCollapseTimer number: MAX_FOLDER_ITEM_IN_MENU_LIST = 5 MAX_HISTORY_MENU_ITEMS = 15 MOUSE_SCROLL_IS_HORIZONTAL = 4 MOUSE_SCROLL_ZOOM = 3 // …​ object Array: // all normal js arrays, like ["hi!", 4711] zzz object HTMLAnchorElement: // more esoteric types also shown node object Location: location object Navigator: navigator object Object: // these are all js literals like { "hi": 4711 } BookmarksEventHandler BookmarksMenuDropHandler BrowserOffline // …​ self [object ChromeWindow]: // all these are self-referential properties, i e this.window === this Firenomics window string: // for strings, we only show ⇐ 40-character string contents: // …​ NEWLINE = "\n" ORGANIZER_FOLDER_ANNO = "PlacesOrganizer/OrganizerFolder" ORGANIZER_QUERY_ANNO = "PlacesOrganizer/OrganizerQuery" ORGANIZER_ROOT_BOOKMARKS = String(/* 54 chars */) undefined: // and finally, all the properties whose value is the undefined value: gWebPanelURI prev

repl> repl.peek(this, /move/i)
object ChromeWindow
5/523 matches // only five directo property names match "move" case insensitively:
number:
  RELOAD_ACTION_MOVE = 3
  RELOAD_ACTION_REMOVE = 2
  REMOVE_PAGES_CHUNKLEN = 300
  REMOVE_PAGES_MAX_SINGLEREMOVES = 10
object Object:
  gEditItemOverlay
repl> repl.peekNative(this);
object ChromeWindow // again, the type of the given object
4/523 matches // only 4 of the 523 direct properties matched the filter
native function:
  XPCNativeWrapper
  XPCSafeJSObjectWrapper
  addEventListener
  getInterface
repl> repl.peekObj(/^XPC/, mozrepl)
object Object // bnothing special about the mozrepl object
    2/12 matches // 2 of its 12 direct properties are objects of an XPC* type
    object XPCWrappedNative_NoHelper:
      pref
      server
</code>
</pre>

h2. Code

<pre> <code> function peek(at, depth, re, typeRe) { function lsKeys(data, level, matches, total) { var types = [], type, header = ''; for (type in data) { if (!data.hasOwnProperty(type)) continue; types.push(type); }

if (matches !== total)
  header = matches +'/'+ total +' matches';
if (level)
  header += (header ? ' on ': '') +'prototype ancestor '+ level +':';
if (header) repl.print('\n' + header);
  types.sort().forEach(function ls(type) {
    repl.print(type +':\n  '+ (data[type].sort().join('\n  ')));
  });
}
if ('number' !== typeof depth) {
  typeRe = re;
  re = depth;
  depth = 0;
}
var l = 0, self = at, self_type = 'self ['+ typeOf(self) +']', intp = /^\d+$/;
do {
  var type = typeOf(at);
  repl.print(type + (/^(?:number|string)$/.test(type) ? ': '+ at : ''));
  if (/^(?:number|string|null|undefined)$/.test(type)) return;
// data[type] = [key, key, ...]
var data = {}, key, val, count = 0, matches = 0;
for (key in at) {
  if (!at.hasOwnProperty(key)) continue;
  if (self_type === 'self [object Array]' && intp.test(key)) continue;
  ++count;
  if (re && !re.test(key)) continue;
  ++matches;
try {
  val = at[key];
  type = typeOf(val);
} catch (e) {
  type = 'unknown';
}
if (typeRe && !typeRe.test(type)) {
  --matches;
  continue;
}
      if (self === val)
        type = self_type;
      else if ('boolean' === type || 'number' === type)
        key += ' = '+ val;
      else if ('string' === type)
        if (val.length < 40)
          key += ' = '+ uneval(val);
        else
          key += ' = String(/* '+ val.length +' chars */)';
      data[type] = (data[type] || []).concat(key);
    }
    lsKeys(data, l++, matches, count);
  } while (depth-- && (at.__proto__ !== at) && (at = at.__proto__));
}

function typeOf(x) { var k, t = null == x ? null === x ? 'null' : 'undefined' : typeof x; if ('function' === t) return /\{\[native code\]\}$/.test(x.toSource()) ? 'native ' + t : t; if ('object' !== t || !(k = Object.prototype.toString.call(x)) || !(k = /^\[object (.*)\]$/.exec(k)) || !(k = k[1])) return t; // number, string, null, undefined, super-weird "object"s // /^(Array|Object|RegExp)$/.test(k) ? k : return t ' ' k; // typed objects }

function peekJSON(o, depth, re) { peek(o, depth || 0, re, /^(?:boolean|number|string|object Object|object Array|null)$/); }

function peekUnJSON(o, depth, re) { peek(o, depth || 0, re, /^(?!(boolean|number|string|object Object|object Array|null)$)/); }

function peekObj(o, depth, re, typeRe) { if ('string' === typeof o || 'object RegExp' === typeOf(o)) { var flags = o.ignoreCase === true ? 'i' : ''; if ('string' != typeof o) o = o.toSource().replace(/^\/|\/$/g, ''); o = '^object '+ (o.replace(/(?!\)/, '.').replace(/\/, '')); return peekObj(depth, re, typeRe, new RegExp(o, flags)); } return peek(o, depth || 0, re, typeRe || /^object /); }

function peekFn(o, depth, re) { peek(o, depth || 0, re, /^(?!native )?function$/); }

function peekNative(o, depth, re) { peek(o, depth || 0, re, /^native function$/); } </code> </pre>