Ruby Ruby DATA

oneapm · 2015年06月18日 · 最后由 oneapm 回复于 2015年06月19日 · 2753 次阅读

这段代码能运行吗?这个 DATA 是什么东西?

require 'erb'

data = DATA.read
title = "hello world!"
content = "hello world!\n"

puts ERB.new(data).result(binding)

__END__

<html>
  <head> <%= title %> </head>
  <body>
    <h1> <%= title %> </h1>
    <p>
      <%= content %>
    </p>
  </body>
</html>

输出结果:

<html>
  <head> hello world! </head>
  <body>
    <h1> hello world! </h1>
    <p>
      hello world!

    </p>
  </body>
</html>

这个的 DATA 是一个 IO 对象,读取__END__之后内容。有一点需要注意的是DATA.read会将__END__之后的内容一次性读出,由于 IO 读取的特性,当第二此DATA.read的时候内容就会为空,如果需要第二次读取,那么先要执行DATA.rewind

有的时候我们写一个脚本来做一些自动化的工作,需要预先读取一个文件的内容,作为输入或者作为模版,我们可以先把这部分内容附到__END__后,然后用DATA来读取,因为它是标准的 IO 对象,我们可以像处理普通文件一样处理__END__后的内容,如上面的代码所示,用来存储ERB内容作为模版,然后再进行处理,非常的方便。


本文由OneAPM工程师原创,欢迎大家来OneAPM做客,共同讨论各种技术问题,OneAPM提供包括Ruby在内的主流 6 种编程语言,以及浏览器端、移动端、服务器软硬件环境的性能监测服务。

这种时候我宁愿用 heredoc

#1 楼 @msg7086 那你认为这种方式的缺点是什么呢?为什么宁愿用 heredoc? 交流一下😄

#2 楼 @oneapm 这种更多的是用在那种一键安装包上的。比如前面是代码,后面带了一个 zip 包,那一个文件比两个更方便。 平时用的话 heredoc 关联性更强,不至于看到你的代码就开始跳跃性思维跳到最后再跳回来……

#3 楼 @msg7086 嗯,其实我们基本上也这么用,虽然没有用 zip 包。我们来做一些系统管理的脚本时,会把模板文件放在后面,有的比较长,脚本本身没多长,倒是模板文件比较长,这时候用 DATA 比较方便,原本两个文件合成一个,并且代码和数据进行了分离,和你的想法是一致的。不过这个 DATA 作为流输入,本身就有很多流的可用方法,相信可用的场景还很多。如果你有过这样的应用场景的话,不妨和我们分享一下。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号