Módulos Appcelerator e CommonJS (caching e referências circulares)

Aqui está a coisa:

Estou usando o modo CommonJS de tornar minha aplicação móvel (iPhone / Android) modular. Nenhuma surpresa lá. Mas há uma coisa que eu simplesmente não consigo entender.

O CommonJS me permite criar variáveis ​​privadas STATIC, o que me permite criar singletons à vontade. Isso, eu acho, pelo menos, é porque o conteúdo de um arquivo que ficarequire()d é lido apenas uma vez e, em seguida, o objeto de exportações (que é inicializado apenas uma vez) é retornado sempre.

Mas quando eu crio uma referência circular como visto abaixo, o código dentro do módulo incluído é executado toda vez.

Esperar... O engraçado é que, enquanto eu estou escrevendo esta pergunta, de repente eu percebo que nenhuma das chamadas pararequire() terminar antes do próximo começar (daí o estouro da pilha demonstrado abaixo).

Qualquer pensamento sobre se estou no caminho certo ou não? Já passamos das 5 da manhã, então todas as apostas estão fora do meu limite: D.

EXEMPLOS:

Veja este pedaço de código, ele define um singleton:

/* Singleton.js */

exports.getSingleton = getSingleton;

function getSingleton(name) {
  if (!instance) {
    instance = new Thing(name);
  }

  return instance;
}

function Thing(name) {
  this.name = name;
}

var instance;

I require() este arquivo como tal:

var theFirstThing = require('Singleton').getSingleton('first');
Ti.API.info('first: ' + theFirstThing.name)

var possiblyAnotherOtherThing = require('Singleton').getSingleton('second');
Ti.API.info('second: ' + possiblyAnotherOtherThing.name);

A saída é:

[DEBUG] loading: /path/to/sim/MyApp.app/app.js, resource: app_js
[DEBUG] loading: /path/to/sim/MyApp.app/Singleton.js, resource: Singleton_js
[INFO] first: first
[INFO] second: first

Por que então referências circulares como as seguintes não funcionam? (Eu poderia já ter perguntado isso, comentar / responder sobre isso, se quiser).

app.js

require('Banana');

Pinapple.js

require('Banana');

Banana.js

require('Pineapple');

Porque a saída é esta:

[DEBUG] loading: /path/to/simulator/MyApp.app/app.js, resource: app_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js

/* etcetera (total of 15 times back and forth) */

[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Banana.js, resource: Banana_js
[DEBUG] loading: /path/to/simulator/MyApp.app/Pineapple.js, resource: Pineapple_js
[ERROR] Script Error = Maximum call stack size exceeded. (unknown file)

questionAnswers(1)

yourAnswerToTheQuestion