17

nodejsのwindow[my_func_name]に相当するものは何ですか? stdin から文字列を読み取っていますが、それが関数名の場合は実行したいと思います。global[my_func_name] が機能する可能性があると思っていましたが、残念ながら機能しません。

4

4 に答える 4

17

それはうまく動作します

global.foo = function foo () {
  console.log("foo was called");
}

process.stdin.on("data", function(input) {

  // don't forget to call .trim() to remove the \n
  var fn = input.toString().trim();

  // function exists
  if (fn in global && typeof global[fn] === "function") {
    global[fn]();
  }

  // function does not exist
  else {
    console.log("could not find " + fn + " function");
  }
});

process.stdin.resume();

出力

foo
foo was called
bar
could not find bar function

これが良いアイデアであるかどうかは...まあ、それはまったく別の議論です.


編集— 約 18 か月後... ええ、そのようなグローバル関数を呼び出すのは恐ろしい考えです。

そうは言っても、より良い方法で問題に取り組むことができる1つの方法があります。以下では、小さなREPL (read-eval-print ループ) を作成します。よりよく理解するために、いくつかの部分に分けて説明します。

まず、ユーザーがコマンドを実行する前に、ユーザーが Enter キーを押すのを REPL が待機するようにします。これを行うには、パイプを下に送信する前に文字を待機する変換ストリームを作成します。"\n"line

以下のコードはES6を使用して記述されています。コードを実行するための互換性のある環境が見つからない場合は、babelを確認することをお勧めします。

// line-unitizer.js
import {Transform} from 'stream';

class LineUnitizer extends Transform {
  constructor(delimiter="\n") {
    super();
    this.buffer = "";
    this.delimiter = delimiter;
  }
  _transform(chunk, enc, done) {
    this.buffer += chunk.toString();
    var lines = this.buffer.split(this.delimiter);
    this.buffer = lines.pop();
    lines.forEach(line => this.push(line));
    done();
  }
}

export default LineUnitizer;

LineUnitizerあなたがストリーム処理に不慣れで、それがまったく意味をなさない場合でも、あまり夢中にならないでください。この種のストリーム変換は非常に一般的です。process.stdin一般的な考え方は次のとおりです。受信ストリームにパイプするprocess.stdinと、ユーザーがキーを押すたびにデータが送信されます。ただし、Repl(以下に実装されている) ユーザーがコマンドの入力を完了するまで、コマンドを実行することはできません。LineUnitizerは、ユーザーが Enter キーを押す ("\n"ストリームに a を挿入する)のを待ってから、処理の_transformためにコマンドを送信する準備ができたことを通知する部分replです!

Repl今見てみましょう

// repl.js
import {Writable} from 'stream';

class Repl extends Writable {
  _parse(line) {
    var [cmd, ...args] = line.split(/\s+/);
    return {cmd, args};
  }
  _write(line, enc, done) {
    var {cmd, args} = this._parse(line.toString());
    this.emit(cmd, args);
    done();
  }
}

export default Repl;

なるほど、簡単でした!それは何をしますか?行を受信するたびreplに、いくつかの引数を持つイベントを発行します。コマンドがどのように解析されるかを視覚的に確認する方法を次に示します。

The user enters       emit event      args
-------------------------------------------------------------
add 1 2 3             "add"           ["1", "2", "3"]
hens chocobo cucco    "hens"          ["chocobo", "cucco"]
yay                   "yay"           []

では、すべてを配線して動作を確認しましょう

// start.js
import LineUnitizer from './line-unitizer';
import Repl         from './repl';

process.stdin
  .pipe(new LineUnitizer())
  .pipe(
    (new Repl())
      .on("add", function(args) {
        var sum = args.map(Number).reduce((a,b) => a+b, 0);
        console.log("add result: %d", sum);
      })
      .on("shout", function(args) {
        var allcaps = args.map(s => s.toUpperCase()).join(" ");
        console.log(allcaps);
      })
      .on("exit", function(args) {
        console.log("kthxbai!");
        process.exit();
      }));

それを実行します

$ node start.js

出力

で始まる行>はユーザー入力です。は>実際には端末に表示されません。

> add 1 2 3
add result: 6
> shout I can see it in your face!
I CAN SEE IT IN YOUR FACE!
> exit
kthxbai!

それが素晴らしいと思うなら、私たちはまだ終わっていません。このようにプログラムを作成する利点は、コマンドがどのようにプログラムに到達したかに関係なく、コマンドに基づいて行動できることです。

commands.txtこのファイルを検討してください

add 100 200
shout streams are the bee's knees
exit

今、このように実行します

$ cat commands.txt | node start.js

出力

300
STREAMS ARE THE BEE'S KNEES
kthxbai!

わかりました、それはかなり素晴らしいことです。ここで、コマンドがどこからでも来る可能性があると考えてください。データベース イベント、ネットワーク上の何か、CRON ジョブなどである可能性があります。すべてが適切に分離されているため、さまざまな入力を簡単に受け入れるようにこのプログラムを簡単に適応させることができます。

于 2013-10-17T18:04:56.257 に答える
0
var theTests = require('./tests'); 
//@TODO CaseID should be caseId
var CaseID = 5678;
// use dynamic functions
var functionName = 'theTests.TEST_' + CaseID;
var functionString = String('TEST_' + CaseID);

var check = eval( 'typeof ' + functionName ); // bad
if ( check == 'function' ) {
    // run the function
    // testResult = eval( functionName ); nope
    testResult = theTests[functionString](); //yep :)
    console.log(testResult);
}
else {
    console.log( 'No test functions for ' + CaseID );
}

この例では、tests.js が探します...

TEST_5678: function(){
     return some thing;
},
于 2016-03-09T22:14:04.107 に答える