jsbin/jsbin — pull request #1889 by remy (2014-08-27 21:22:06+00:00)
Title: Fixed #1888

Okay, bear with me, this is complicated.

When using console.log, we want the *right* line that the logging happened on to appear in the native console. To achieve this, we need the *actual* log (or warn or error) function call to happen on the original line in the user's code.

However, since we *also* need to send an update to our own logger, we monkeypatch the console object that the user has access to.

The net result, is the user's code is changed from:

```js
console.log('something', object, [1,2,3]);
```

To:

```js
console.log('something', object, [1,2,3])._()();
```

This is *three* (yes, count them) separate function calls now.

1. To our custom console *and* the arguments are cached
2. To this system to flag that our monkeypatched code has run
3. To finally call the native log (with the cached args applied)

It's important to note that the first call returns an object that has a single property method `_`. The reason for this is because if the `_` method isn't called immediately, we'll fire the native logging for the user (at the cost of losing the original line).

Why? This is because the user may include an external script that we *can't* run our regexp on (to apply the `._()()`).

When the user code has a log, warn or error, we cache a function that can call the native console log with their arguments. This is the `pending` variable.

When the `_()` function is called, it clears the `pending`.

If a logger is called again whilst there's a `pending` function, it first runs the outstanding pending logger, and only then carries on - this ensure the logs come out in the right order.

Finally, as a backup, a `setTimeout(0)` is used in case there's a break in the event loop, which will check for any pending logging and flush if necessary.