今回の問題は前回のとよく似ていますが、今回は modules の概念を使いましょう。問題の解決には2つのファイルが必要になります。

与えられたディレクトリーからファイルの拡張子でフィルタリングされたファイルのリストを出力するプログラムを書いてください。ーつ目の引数はディレクトリー名、二つ目は拡張子です。1行に1ファイルずつコンソールに出力してください。非同期 I/O を使ってください。

module ファイルに処理の大部分を書いてください。module は、3つの引数を取る関数を一つだけ定義してください。引数は ディレクトリー名、ファイル拡張子、それからコールバック関数、という順序です。ファイル拡張子の引数はそのままプログラム本体に渡してください。つまり、正規表現に変換したり "." を付けたりしてはいけません。

コールバック関数は Node の習慣的なイディオムを使って呼び出してください: (err, data) 。このイディオムで言うとエラーのない場合はーつ目の引数 (err)は null です。2つ目にはデータが入っています。今回の問題の場合にはファイルリストの Array です。 エラーの場合(つまり: fs.readdir() で問題があった場合)は、そのエラーだけを一つ目の引数としてコールバック関数に渡してください。

コンソールへの出力は module ではなく、本体のプログラムでのみ出力してください。

エラーの場合はわかりやすいエラーメッセージを出力してください。

まとめ:つまり、あなたの module は、以下の4点の制約を守ってください。

  1. 正しく引数を取る関数を定義してください。
  2. エラーか何らかのデータを引数に取るコールバックを1度だけ呼び出してください。
  3. 他には何も変えないでください(グローバル変数や標準出力)
  4. 発生する可能性のあるエラーは全てコールバック関数に渡してください。

この制約の良いところはこれを守っている module であれば誰にでも扱えることです。


ヒント

フォルダーの内容を読み、フィルタする Module を書くためにそれを新しいファイルに書いてください。一つの関数だけ を定義するためには、以下の例のように module.exports を利用します。:

module.exports = function (args) { /* ... */ }

あるいは名前がある関数を名前を使って定義してもいいです。

function hoge() {
    /* ... */
}

module.exports = hoge

あなたの新い Module を使うために require() を使ってください。 require('fs')fs をロードすると同じように。ただ、一つの大切な違いはローカルの Module のために './' を使ってください。あなたの Module の名前は mymodule.js だったらこのように使ってください:

var hoge_module = require('./mymodule.js')

(メモ: '.js' の拡張子はこの場合必ずしも必要ではありません。他のコードではそれはよく省略しています。)

上記コードによって Module に書いてある module.exports の Object にアクセスできます。それは hoge_module 変数に格納されます。mymodule.js には一つの関数だけが定義されているので、 hoge_module 変数そのものが実行可能な関数です!

hoge_module();

イディオムのエラーチェックと return を忘れないでください:

function bar (callback) {
  foo(function (err, data) {
    if (err)
      return callback(err) // 早めの `return` が大事。

    // ... エラーのない場合、そのまま `data`を使って楽しんでください。

    // 十分楽しく過ごしてからはエラーの引数を `null` にしてください。
    callback(null, data)
  })
}