<commit_before>
module.exports = chain;

var method = require(__dirname).method;

// steps, cb
// Each step is either:
// [fn, arg, arg, arg] or
// [obj, "method", arg, arg, arg]
// The eventual cb passed to chain is resolved with an array of
// all the results, and/or an error if one was returned.
function chain () /* step, step, ..., cb */ {
  var steps = Array.prototype.slice.call(arguments, 0),
    cb = steps.pop();

  if (typeof(cb) !== "function") {
    throw new Error("Invalid callback: "+typeof(cb) + " " +sys.inspect(cb));
  }
  
  (function S (step, results) {
    if (!step) return cb(null, results);
    var fn = ( typeof step[0] === "object" )
      ? method(step.shift(), step.shift())
      : step.shift();
    step.push(function (er, ok) {
      if (er) cb(er, results);
      else {
        results.push(ok);
        S(steps.shift(), results);
      }
    });
    try {
      fn.apply(null, step);
    } catch (er) {
      cb(er, results);
    }
  })(steps.shift(), []);
}
<commit_msg>Don't use the method() function in chain, because that means that the function is wrapped and scope-corrected twice, which is silly.  Just use the obj if it's specified, and take either a string method name or a function.<commit_after>
module.exports = chain;

// steps, cb
// Each step is either:
// [fn, arg, arg, arg] or
// [obj, "method", arg, arg, arg]
// The eventual cb passed to chain is resolved with an array of
// all the results, and/or an error if one was returned.
function chain () /* step, step, ..., cb */ {
  var steps = Array.prototype.slice.call(arguments, 0),
    cb = steps.pop();

  if (typeof(cb) !== "function") {
    throw new Error("Invalid callback: "+typeof(cb) + " " +sys.inspect(cb));
  }
  
  (function S (step, results) {
    if (!step) return cb(null, results);
    var obj, fn;
    if (typeof step[0] === "object") {
      obj = step.shift();
    }
    if (typeof step[0] === "function") {
      fn = step.shift();
    } else {
      fn = obj[step.shift()];
    }
    step.push(function (er, ok) {
      if (er) cb(er, results);
      else {
        results.push(ok);
        S(steps.shift(), results);
      }
    });
    try {
      fn.apply(obj, step);
    } catch (er) {
      cb(er, results);
    }
  })(steps.shift(), []);
}

{'fraction_non_alphanumeric': 0.1737791465024197, 'fraction_numerical': 0.002199736031676199, 'mean_word_length': 2.547581903276131, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5729594', 'n_tokens_mistral': 756, 'n_tokens_neox': 741, 'n_words': 244}