知らないとやばいreadlineモジュール

`readline` モジュールは、Node.js の標準ライブラリの一部であり、コマンドラインインターフェース（CLI）を作成する際に非常に便利です。ユーザーからの入力を行ごとに読み取るための機能を提供します。以下に、`readline` モジュールでよく使われるメソッドやイベントを説明します。

---

### **1. `readline.createInterface(options)`**

- **説明**: 新しい `readline.Interface` インスタンスを作成します。
- **引数**:
  - `input`: 読み取り用のストリーム（通常は `process.stdin`）。
  - `output`（オプション）: 書き込み用のストリーム（通常は `process.stdout`）。
- **使用例**:

  ```javascript
  const readline = require('readline');

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  ```

---

### **2. `rl.question(query, callback)`**

- **説明**: ユーザーに `query` を表示し、入力を待ちます。入力が完了すると `callback` 関数が呼び出されます。
- **引数**:
  - `query`: ユーザーに表示する質問（文字列）。
  - `callback`: ユーザーの入力を受け取る関数。
- **使用例**:

  ```javascript
  rl.question('あなたの名前は何ですか？ ', (answer) => {
    console.log(`こんにちは、${answer}さん！`);
    rl.close();
  });
  ```

---

### **3. `rl.on('line', listener)`**

- **説明**: ユーザーが入力し、Enter キーを押すたびに `line` イベントが発生し、`listener` 関数が呼び出されます。
- **引数**:
  - `listener`: 入力された行を受け取る関数。
- **使用例**:

  ```javascript
  rl.on('line', (input) => {
    console.log(`入力内容: ${input}`);
  });
  ```

---

### **4. `rl.prompt()`**

- **説明**: 設定されたプロンプトを表示します。`rl.on('line')` と組み合わせて使用します。
- **使用例**:

  ```javascript
  rl.setPrompt('> ');
  rl.prompt();

  rl.on('line', (input) => {
    console.log(`入力内容: ${input}`);
    rl.prompt();
  });
  ```

---

### **5. `rl.setPrompt(prompt)`**

- **説明**: `rl.prompt()` で表示されるプロンプト文字列を設定します。
- **引数**:
  - `prompt`: プロンプトとして表示する文字列。
- **使用例**:

  ```javascript
  rl.setPrompt('コマンドを入力してください: ');
  ```

---

### **6. `rl.close()`**

- **説明**: `readline.Interface` インスタンスを閉じ、入力・出力ストリームを解放します。
- **使用例**:

  ```javascript
  rl.close();
  ```

---

### **7. `rl.pause()`**

- **説明**: 入力ストリームを一時停止し、データをバッファします。
- **使用例**:

  ```javascript
  rl.pause();
  // 必要な処理を行う
  rl.resume();
  ```

---

### **8. `rl.resume()`**

- **説明**: 一時停止した入力ストリームを再開します。
- **使用例**:

  ```javascript
  rl.resume();
  ```

---

### **9. `rl.write(data, key)`**

- **説明**: 出力ストリームにデータを書き込みます。ユーザーの入力行を操作することも可能です。
- **引数**:
  - `data`: 出力する文字列。
  - `key`（オプション）: 特殊キー入力をシミュレートするオブジェクト。
- **使用例**:

  ```javascript
  rl.write('こんにちは、');
  rl.write(null, { ctrl: true, name: 'u' }); // 行をクリア
  rl.write('世界！');
  ```

---

### **10. `rl.history`**

- **説明**: ユーザーが入力した行の履歴を保持する配列です。
- **使用例**:

  ```javascript
  console.log(rl.history);
  ```

---

### **11. `rl.clearLine(direction)`**

- **説明**: 現在の行をクリアします。
- **引数**:
  - `direction`: 行のクリア方法を指定します。`-1`（カーソルから左をクリア）、`1`（カーソルから右をクリア）、`0`（行全体をクリア）。
- **使用例**:

  ```javascript
  readline.clearLine(process.stdout, 0);
  ```

---

### **12. `rl.clearScreenDown()`**

- **説明**: カーソル位置から下の画面をクリアします。
- **使用例**:

  ```javascript
  readline.clearScreenDown(process.stdout);
  ```

---

### **13. イベント `'close'`**

- **説明**: `rl.close()` が呼び出されたとき、または入力ストリームが終了したときに発生します。
- **使用例**:

  ```javascript
  rl.on('close', () => {
    console.log('インターフェースが閉じられました。');
  });
  ```

---

### **14. イベント `'SIGINT'`**

- **説明**: `Ctrl+C` が押されたときに発生します。
- **使用例**:

  ```javascript
  rl.on('SIGINT', () => {
    rl.question('終了しますか？ (y/n) ', (answer) => {
      if (answer.match(/^y(es)?$/i)) rl.pause();
      else rl.prompt();
    });
  });
  ```

---

### **15. イベント `'SIGTSTP'` と `'SIGCONT'`**

- **説明**: `SIGTSTP`（`Ctrl+Z`）と `SIGCONT` シグナルを受け取ったときに発生します。
- **使用例**:

  ```javascript
  rl.on('SIGTSTP', () => {
    console.log('SIGTSTP 受信');
    // 必要に応じて処理を追加
  });

  rl.on('SIGCONT', () => {
    console.log('SIGCONT 受信');
    // 必要に応じて処理を追加
    rl.prompt();
  });
  ```

---

### **追加のポイント**

- **非同期処理**: `rl.question` は非同期的に動作します。ユーザーの入力を待つ間、他の処理を行うことができます。
- **REPL の作成**: `rl.prompt()` と `rl.on('line')` を組み合わせることで、簡単な REPL（Read-Eval-Print Loop）を作成できます。
- **入力検証**: ユーザーの入力を検証し、再度プロンプトを表示することで、期待する形式の入力を受け取ることができます。

---

### **実用的な例**

以下は、シンプルなコマンドラインインターフェースの例です。

```javascript
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: 'コマンドを入力してください> ',
});

console.log('簡単な CLI アプリケーションへようこそ！');
rl.prompt();

rl.on('line', (line) => {
  switch (line.trim()) {
    case 'こんにちは':
      console.log('こんにちは！');
      break;
    case '終了':
      rl.close();
      break;
    default:
      console.log(`不明なコマンド: '${line.trim()}'`);
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('ご利用ありがとうございました！');
  process.exit(0);
});
```

---

### **公式ドキュメント**

さらに詳細な情報や追加のメソッドについては、公式ドキュメントを参照してください。

- [Node.js `readline` モジュール公式ドキュメント](https://nodejs.org/api/readline.html)