DATA.each_line do |line| puts line end __END__ Doom Quake Diablo
关于这个技术我最喜欢的实例是使用 DATA 来包含一个 ERB 模板。它同样也可用于 YAML、CSV等等。
1 2 3 4 5 6 7 8
require'erb' time = Time.now renderer = ERB.new(DATA.read) puts renderer.result() __END__ The current time is <%= time %>.
实际上你也可以使用 DATA 来读取 __END__ 关键字以上的内容。那是因为 DATA 实际上是一个指向了整个源文件,并定位到 __END__ 关键字的位置。你可以试试看在输出之前将 IO 对象反转。下面这个例子将会输出整个源文件。
1 2 3 4 5
DATA.rewind puts DATA.read # prints the entire source file __END__ meh
多文件问题
这个技术最大的缺点是它只能用于单个文件的脚本,直接运行该文件,不能在其他文件进行导入。
下面这个例子,我们有两个文件,并且每个都有它们自己的 __END__ 部分。然而却只有一个全局 DATA 对象。因此第二个文件的 __END__ 部分刚访问不到了。
1 2 3 4 5 6 7 8 9 10
# first.rb require"./second" puts "First file\n----------------------" puts DATA.read print_second_data() __END__ First end clause
1 2 3 4 5 6 7 8 9 10
# second.rb defprint_second_data puts "Second file\n----------------------" puts DATA.read # Won't output anything, since first.rb read the entire file end __END__ Second end clause
1 2 3 4 5 6 7
snhorne ~/tmp $ ruby first.rb First file ---------------------- First end clause Second file ----------------------
# This code is from the Sinatra docs at http://www.sinatrarb.com/intro.html require'sinatra' get '/'do haml :index end __END__ @@ layout %html = yield @@ index %div.title Hello world.
sinatra 是如何实现的呢?毕竟你的应用可能是运行在 rack 上。在生产环境中你不能再通过 ruby myapp.rb 来运行!他们必须有一种在多文件中使用 DATA 的解决方案。
# I'm paraphrasing. See the original at https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1284 app, data = File.read(__FILE__).split(/^__END__$/, 2)
最近刚切换到 Mac 平台上,感觉各种不适应。之前使用 Ubuntu 时,有 service 命令可以对服务进行管理, 但是在 Mac 系统下没有对应的工具。也许有人说可以用 launchctl 啊。但是 launchctl 的服务是开机自动启动的, 而我又不想要开机自动启动,只想在需要时启动,使用完后就停止。
[unix_http_server] file=/tmp/supervisor.sock ; path to your socket file
[supervisord] logfile=/usr/local/var/log/supervisord/supervisord.log ; supervisord log file logfile_maxbytes=50MB ; maximum size of logfile before rotation logfile_backups=10 ; number of backed up logfiles loglevel=error ; info, debug, warn, trace pidfile=/usr/local/var/run/supervisord.pid ; pidfile location nodaemon=false ; run supervisord as a daemon minfds=1024 ; number of startup file descriptors minprocs=200 ; number of process descriptors user=root ; default user childlogdir=/usr/local/var/log/supervisord/ ; where child log files will live