免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4198 | 回复: 1
打印 上一主题 下一主题

Ruby 元编程 - __FILE__ 和 __LINE__ 的作用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-14 14:56 |只看该作者 |倒序浏览
转:darkbaby123

Ruby 元编程 - __FILE__ 和 __LINE__ 的作用  



Ruby 元编程中,经常可以看到各种 eval 和 heredoc 的结合。其中很多用 heredoc 的位置都会出现 __FILE__ 和 __LINE__ 这两个变量。本文介绍一下它们的作用,以及为什么要这样做。

正文
先看一个用 class_eval 动态生成实例方法的例子:

view sourceprint?
  1. 01 class A

  2. 02   def self.my_attr_reader(*args)  

  3. 03     args.each do |method|  

  4. 04       class_eval <<-EOF, __FILE__, __LINE__

  5. 05         def #{method}  

  6. 06           raise "#{method}"

  7. 07         end

  8. 08       EOF

  9. 09     end

  10. 10   end

  11. 11 end
复制代码
这是模仿 Ruby 的 attr_reader 的代码,当然实现简化过了,关键是,它会抛出异常。我们待会再解释为什么这样做。现在先大概解释下代码。

class_eval 是 Ruby 中 eval 的一种,它的上下文是调用它的对象,也就是类 A 。它通常用来为类生成实例方法,用法就像上面代码中的那样。你可以传把一段 Ruby 代码写在一个字符串中传过去,class_eval 就会动态解释 Ruby 代码。这和 Javascript 中的 eval 十分类似。

heredoc 就是被 EOF 包起来的那部分。它实际上是一个多行的字符串,EOF 只是一个标识,代表 heredoc 的开始和结束,你可以随意换成其他玩意。用 heredoc 的好处之一是可以不用操心单引号和双引号的问题,还有就是把代码写在多行看得比较清楚。喜欢深挖的可以看看 这个链接。

第4行 EOF 后面的 __FILE__ 和 __LINE__ 是两个特殊变量,它们保存了当前文件的名字和当前代码的行数。其实 heredoc 后面不加这两个变量也可以。比如这样也是合法的:


view sourceprint?
  1. 1 class_eval <<-EOF

  2. 2 EOF
复制代码
那加了它们有什么好处呢?

主要还是在测试方面。我们可以用如下代码测试一下:

view sourceprint?
  1. 1 A.class_eval do

  2. 2   my_attr_reader :name

  3. 3 end

  4. 4   

  5. 5 a = A.new

  6. 6 a.name      # 会抛出异常,异常信息为 name
复制代码
把这段代码和上面第一段放在一起,保存成 Ruby 文件(我保存成 test.rb),再用解释器执行,会看到如下的错误:

view sourceprint?
  1. 1 # test.rb:5:in `raise': exception object expected (TypeError)  

  2. 2 #     from test.rb:5:in `name'  

  3. 3 #     from test.rb:18
复制代码
可以看到,异常信息会提示你错误出在 test.rb 第5行的 name 方法内。即使 name 方法是用元编程手段动态产生的。

现在我们把 EOF 后面的 __FILE__ 和 __LINE__ 去掉。再运行下代码,会看到如下的结果:


view sourceprint?
  1. 1 # (eval):2:in `raise': exception object expected (TypeError)  

  2. 2 #     from (eval):2:in `name'  

  3. 3 #     from test.rb:18
复制代码
可以看到,异常信息最后是从 eval 中抛出来的,最多只能看到18行调用 name 的那一行出错了,但看不到 name 方法在哪定义的。这样对 debug 几乎没有帮助,尤其是当程序复杂的时候。比如 Rails 就使用了大量元编程技巧。

所以,__FILE__ 和 __LINE__ 在这里就是为了方便 debug 的。它们并不会对元编程动态创建的方法有任何影响。

论坛徽章:
0
2 [报告]
发表于 2011-06-14 22:13 |只看该作者
想起了Python。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP