Scala,Maven和预处理器

时间:2010-08-03 11:37:12

标签: java maven-2 scala m4 preprocessor

我知道Java中预处理器和宏的所有哲学论据。我不同意,因为有些人可能会滥用语言功能,所以应该排除所有语言功能。

我想在我的Java和Scala代码中包含__FILE____LINE__宏,以实现高效的日志记录。由于运行时性能的影响,任何使用Exception都是不可接受的。那些认为可以在“生产代码”中关闭日志记录的人应该听取Brian Kernighan的建议:

  

删除错误消息“现在程序正在运行”就像在地上戴降落伞一样,但是一旦你在空中就把它取下来。

这些宏是否有可能使其成为语言?如果没有,有没有办法使用Maven运行像m4这样的预处理器?

感谢。

4 个答案:

答案 0 :(得分:1)

恕我直言,实现这一目标的“正确”方法是编写一个编译器插件来执行替换,但是真的值得付出这么多努力吗?

答案 1 :(得分:1)

<强>更新 @ralph 嗯,这是2年多以前的一个问题,但由于我对__LINE____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被替换为描述其在源代码中的位置的文字字符串。例如,在第13行放入println,它会显示:

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

我没有广泛使用这些机制,但通过调整这个东西,可以开发他需要的日志记录功能(我应该补充一点,编写宏可能很困难 - 这对我来说!)。

答案 2 :(得分:0)

无论如何,记录应该是一个贯穿各领域的问题。可以用方面做你想做的事。

答案 3 :(得分:0)

您可以使用编译器API执行此操作,但要小心。注释处理器/编译器插件的“规则”声明它们不应该修改正在生成的类。 Sun / Oracle可以随时强制执行此操作。

现在,请查看http://projectlombok.org。它使用编译器API生成getter,setter等。它们具有可用作模型的源代码,或者您可以为它们提供处理程序。

您可能会执行以下操作:

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是否会实际执行“不要修改正在生成的类”规则,但他们可以。