2012-11-24 15 views
2

我已经构建了一个小型编译器,用于静态类型的语言。在了解静态语言如何工作之后,我很难将自己的头脑变成像Groovy这样的动态语言。Groovy如何以动态方式工作?

在构建我的编译器时,我知道一旦生成机器级代码,就无法更改它! (即其run-time)。

但这是如何做到的Groovy这个神奇的东西一样一样的语句推断类型:

def a = "string" 
a.size() 

就我而言,常规必须找到类型astring运行线a.size()之前。它似乎是在编译时(在构建AST时)这样做的!但是这种语言被称为动态的。

我很困惑,请帮我弄清楚。

谢谢。

+2

输入推理!=动态输入 –

+0

也许这个网页将帮助:http://groovy.codehaus.org/Runtime+vs+Compile+time,+Static+vs+Dynamic。基本上groovy可以在静态和动态类型之间切换。 – Alex

回答

3

Groovy不是简单地“调用”一个方法,而是通过元对象协议调度它。方法调用被发送到作为消息到对象,它可以响应或不响应。使用动态类型时,只有在响应该消息时才与对象类型无关。这叫做duck typing

当你反编译Groovy代码时,你可以看到它(尽管不是很容易)。您可以使用groovyc编译并使用其他工具反编译。我建议jd-gui。由于Groovy的方法缓存(通过这种方式实现Groovy的整洁性能),您不会看到明确调用的方法。

对于这样一个简单的脚本:

def a = "abcdefg" 
println a.substring(2) 

这将是生成的代码:

CallSite[] arrayOfCallSite = $getCallSiteArray(); Object a = "abcdefg"; 
return arrayOfCallSite[1].callCurrent(
    this, arrayOfCallSite[2].call(a, Integer.valueOf(2))); return null; 

而且方法调用“调度”的对象,而不是直接调用。这与Smalltalks和Ruby方法派发类似。正是由于这种机制,您可以拦截Groovy对象的方法和属性访问。

由于Groovy 2,Groovy代码可以静态编译,因此就像您的编译器一样。

+0

请注意,使用Jad,您可以“发现”调用哪个方法,因为它提供缓存方法'arrayOfCallSite [2] =“substring”'例如。我个人从JAD获得缓存方法,然后使用JD-GUI显示反编译的java,因为它更清晰(JAD生成包含所有闭包的文件)。 –

相关问题