__LINE__ 和 __FILE__ 常量在 Ruby 中是如何实现的?

14

看起来,在执行过程中,__FILE____LINE__常量会动态更新为当前文件和行号。我想知道这种行为在Ruby中是如何实现的?

我已经搜索了源代码,但出现了太多关于__LINE____FILE__的噪声,我想知道是否有人能帮我指向源代码,并提供理解其行为的线索。

RubinisMRI中解释都可以。


2
也许看一下源代码? - Cody Caughlan
1
为什么要踩?在我看来这是一个好问题。 - Sergio Tulentsev
1
@CodyCaughlan:你能指出相关的文件/行吗?我自己也很好奇 :) - Sergio Tulentsev
1
@CodyCaughlan,你能帮忙指出源代码中的文件:行吗?我用grep查找了__LINE__,但是噪音太多,很难准确地定位到代码。如果你能帮忙,我将非常感激! - steveyang
1个回答

14

__FILE____LINE__都会被文字直接替换在解析器中

case keyword__FILE__:
    return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
                                                rb_filesystem_encoding()));
case keyword__LINE__:
    return NEW_LIT(INT2FIX(tokline));

换句话说,它们的行为就像您自己键入生成的字符串或数字一样。
请注意,对于__LINE__,这并不总是按您所期望的方式

@hammar 感谢提供源代码。我对解析器不熟悉,__FILE____LINE__都是从静态函数gettable_gen中调用的。这是否意味着每次从Ruby调用__LINE__时,都会调用NEW_STR()来生成动态值? - steveyang
@steven.yang:不,解析只会在加载文件时发生一次。之后就没有对__LINE__的“调用”了。从那时起,它们都是常量。这就像在运行程序之前,你把你的Ruby文件交给一个朋友,让他手动替换每个__FILE__出现的位置为文件名,每个__LINE__出现的位置为行号,然后你加载该文件到Ruby中一样。 - hammar
@hammar那么,为什么__LINE__作为一个常量在程序执行时会被更新。这个变量不应该指向一个固定的内存空间。我的第一次理解是每次解析__LINE__时都会调用NEW_LIT - steveyang
你的意思是将每个 __LINE__ 的出现(无论是在第二行、第三行等)一次性替换为该表达式所在的行数吗? - steveyang
@hammar 谢谢。我终于明白了。对不起,我缺乏有关解析器工作原理的基本知识。 - steveyang
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接