4

私は、Javaのプリプロセッサとマクロに対する哲学的な議論をすべて知っています。一部の人が言語機能を悪用する可能性があるという理由だけで、それをすべての人から除外する必要があることに同意しません。

効率的なロギングのために、JavaとScalaのコードにマクロ__FILE__を含めたいと思います。__LINE__実行時のパフォーマンスに影響するため、例外の使用は受け入れられません。「本番コード」でロギングをオフにできると主張する人々は、BrianKernighanのアドバイスに注意する必要があります。

「プログラムが機能している」というエラーメッセージを削除することは、地面にパラシュートを着るようなものですが、空中に出たらパラシュートを外します。

これらのマクロが言語に組み込まれる可能性はありますか?そうでない場合、Mavenを使用してm4のようなプリプロセッサを実行する方法はありますか?

ありがとう。

4

4 に答える 4

1

@ralphを更新__LINE__します。これは2年以上前の質問ですが、私も同じ必要性を持っているので__FILE__、あなたはSCALAについて言及していました。Scalaマクロを使用して私が持っているいくつかのアイデアがあります(v2.10.0-RC1以降

def $currentPosition:String = macro _currentPosition;
def _currentPosition(c:Context):c.Expr[String]={ import c.universe._;
  val pos = c.enclosingPosition;
  c.Expr(Literal(Constant(
    s"${pos.source.path}: line ${pos.line}, column ${pos.column}" )))
}

コンパイル時に評価されるマクロ$currentPositionは、ソースコード内での位置を説明するリテラル文字列に置き換えられます。たとえば、println13行目にを入力すると、次のように表示されます。

/sandbox/tmp_juno_workspace2/LogMacro_Test/src/test/Trial.scala: line 13, column 15

私はこれらのメカニズムをあまり試していませんが、それを微調整することで、必要なロギング機能を開発できます(マクロの作成は難しい場合があることを付け加えておきます-それは私にとってです!)。

于 2012-11-04T09:25:49.240 に答える
1

私見これを達成するための「正しい」方法は、置換を実行するコンパイラプラグインを作成することですが、それは本当にその量の努力の価値がありますか?

于 2010-08-03T12:16:13.630 に答える
0

とにかく、ロギングは横断的関心事でなければなりません。アスペクトでやりたいことができます。

于 2010-08-03T11:55:44.717 に答える
0

コンパイラAPIを使用してこれを行うことができますが、注意してください。アノテーションプロセッサ/コンパイラプラグインの「ルール」は、生成されるクラスを変更することは想定されていないことを示しています。Sun / Oracleは、これをいつでも実施できます。

今のところ、http://projectlombok.orgを覗いてみてください。コンパイラAPIを使用して、ゲッター、セッターなどを生成します。それらには、モデルとして使用できるソースコードがあります。または、ハンドラーを提供することもできます。

あなたはおそらく次のようなことをすることができます:

public class Foo {
  @FileName private static String fileName;
  @LineNumber private static int lineNumber;
  ...
  public void foo() {
     log(fileName, lineNumber, "some message");
  }
}

次に、注釈プロセッサにfileNameとlineNumberの参照を実際のファイル/行に変更させます。

これは、後のJDKバージョンで機能しなくなる可能性があることに注意してください。Sun / Oracleが実際に「生成されるクラスを変更しない」ルールを適用するかどうかはわかりませんが、適用できます。

于 2010-08-04T14:54:35.267 に答える