这是来自O’Reilly Network的一篇关于如何如何使用Ruby及ActiveRecord编写控制台程序的教程,文章通过一个例子程序EarGTD演示了编写控制台程序需要注意的方方面面(文件布局,数据库连接等等),作者是Gregory Brown,你可以在这里找到原文 ,这是第二部分。
手动编写Rakefile
在Rails中,你可能经常会用到Rake来完成各种自动化任务(比如单元测试,数据库迁移等),但是你可能并不清楚该如何添加一个新的Rake任务,或 者是从头写一个新的Rakefile,下面就让我们来看看EarGTD是如何通过Rake来实现它的单元测试自动化的,实际上,并不负责:
require "rubygems"
require "rake"
require "rake/testtask"
task :default => [:test]
Rake::TestTask.new do |test|
test.libs << "test"
test.test_files = Dir[ "test/test_*.rb" ]
test.verbose = true
end
这段代码应该不难理解,它新建了一个Test任务来运行所有test目录下的名为test_XXX.rb的文件,并将test任务设为默认任务,也就是你只需要通过简单的rake命令,而不需要指定参数就可以执行test任务了,
使用module来组织你的代码
虽然只是一个简单的控制台程序,但为了易于维护,我们还是应该尽量保持代码的简洁明了,处于对面向对象的景仰,你可能首先想到的是要定义一个类,就像下面这样:
module A
def b
puts "this is b"
end
end
class C
include A
end
d = C.new
d.b #=> "this is b"
这看起来不错,但是如果你的应用很简单,并不需要维护状态(就像EarGTD),那就没有必要使用类,你可以直接使用module:
module A
# module_function
def b
puts “this is b”
end
end
A.b #=> “this is b”
这样使代码看起来更简洁一些,如果你看过根目录下的earGTD文件,那么你就会发现,它只有那么短短的几行:
#!/usr/bin/env ruby
require "lib/ear_gtd"
EarGTD.connect
EarGTD.process_command(ARGV)
我们可以看到,大部分工作都是在process_command中完成的。
处理命令行
对于EarGTD来讲,它的很大一部分工作就是处理命令行,因此,为了保证代码的整洁,有必要将命令行处理放到一个单独的函数中去,Ruby默认将所有的 命令行参数存放在一个名为ARGV的变量中,EarGTD对命令行的处理策略是取出第一个参数,然后将剩余的参数放在一个数组中:
def process_command(cmd)
args = Array(cmd)
command = args.shift
case(command)
when "+"
add_task(args[0])
when "@"
t = tasks
puts t.empty? ? "Looks like you have nothing to do.\n" : t
# ... other commands omitted
else
puts "Que?"
end
end
这样的好处是可以将你其余的代码同用户界面分离开来,但是命令行处理器需要知道其他接口要操作的数据格式。