字节码编织与Lisp宏


11

我一直在阅读人们为Java和C#等语言编写的库,这些库利用字节代码编织来完成诸如拦截函数调用,插入日志记录代码之类的事情。我还一直在阅读Lisp / Clojure宏试图更好地了解如何利用它们。我对宏的了解越多,它们似乎提供的功能与字节码编织库相同。功能是指在编译时处理代码的能力。

我一直在查看的库示例包括AspectJ,PostSharp和Cecil。

有什么可以做的而不是另一种?他们实际上解决了相同的问题,还是我在比较苹果和橙子?


2
当您需要动态语言但被静态类型的语言所困扰时,字节码编织是一种解决方法
kevin cline 2013年

2
@kevincline您是否正在认真尝试开始这场古老的战斗?
乔纳森·亨森

Answers:


10

字节码编织和宏是两回事。

字节码编织是一种拦截函数调用的方法,因此您可以在函数执行之前或之后将某种功能(通常是诸如日志记录之类的跨领域问题)注入到函数调用中。字节码编织在字节码级别完成,这意味着它编译发生。该功能本身不受影响。这是面向方面的编程使用的技术之一。

宏是扩展语言语法的一种方法。在最简单的形式中,宏只是记录击键,然后使用热键播放击键的一种方法。语言宏的工作方式与此类似。关键字或其他语法构造替代了某种形式的宏扩展。当然,这过于简单了;可以在这里找到特定于Lisp的宏的更好示例。


+1表示这是实现AOP的关键方法。
乔纳森·亨森

交易...让我们不要忘记交易。
乔纳森·亨森

3
LISP宏与“记录击键的一种方式”不同。
凯文·克莱恩

1
答案IMO缺少一些基本概念,可能是:AST,反射,元圆度。
AndreasScheinert

2
@AndreasScheinert:OP没有问任何这些事情。这不是论文。这只是对OP问题的答案。
罗伯特·哈维

5

尽管LISP宏可能用于同一目的,但它们与Java字节码编织插件完全不同。LISP宏在LISP源代码级别扩展了LISP语法。由于LISP宏与其他LISP代码在同一级别上编写,因此它们是常用的语言功能。

Java字节码编织插件在JVM级别运行。尽管许多Java程序员可能会使用其他人编写的字节码编织插件,但很少有Java程序员编写自己的字节码编织插件。

Java编译器插件完成的某些工作很容易用动态语言完成。函数调用拦截特别简单。


我了解两者之间的技术差异。我试图从较高的角度来看这个问题。两种工具都可以操纵代码来实现相同的目标吗?宏不能解决字节码操作可以解决的任何问题吗(以理智且经济高效的方式)?那是我想要的。
mortalapeman

@mortalapeman:通过字节码修改可以在Java和C#中进行的所有操作都可以直接在Lisp,Ruby,Python,Lua,Javascript等语言中完成...大概可以完成LISP宏可以通过字节进行的所有操作代码操作,但实际上不会发生。
凯文·克莱恩

4

Lisp宏在源代码级别运行。如果将一些宏包装在一段代码周围,那么您可以做很多事情。包括解析源代码,插入代码,重写代码等。

如果要修改函数调用,Lisp通常使用两种机制:

  • 后期绑定符号。您可以修改绑定到符号的功能。每个调用一个符号的函数,然后使用新函数。

  • Lisp实现有时会提供一个称为“建议”的功能。这允许在调用之前,之后或周围执行代码。例如在LispWorks中:Advice

因此,您可以拦截调用而无需进行低级代码操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.