我正在编写一个ruby gem,用户可以安装它并使用命令行ruby工具与服务交互。您可以启动和停止服务(它将从一个子进程中产生)。
我已经对编写网络服务的最佳方法做了很多研究,比如说websphere MQ/EventMachine,我了解了如何创建一个Ruby gem,它将安装一个可以在命令行中使用的二进制文件,但我正在努力制定一个好的代码结构。
我的命令行实用程序将接受各种参数(我将使用Trollop),它将使用各种类来做事情,并使用各种其他ruby宝石。
我不确定我应该把类文件放在哪里,以及如何要求它们在二进制文件中,以便路径正确。
在很大程度上,RubyGems将为您解决这一问题。您需要将可执行文件包括在files
列表中,并将其放在gemspec的executables
中。通常将可执行文件放在目录中的bin
中,例如:
$ ls
bin/ myapp.gemspec lib/ Rakefile
$ ls bin
bin/myapp
你的宝石规格会看起来像:
Gem::Specification.new do |s|
s.name = 'myapp'
# whatever else is in your gemspec
s.files = ["bin/myapp","lib/myapp.rb"] # or whatever other files you want
s.executables = ["bin/todo"]
end
此时,当用户通过RubyGems安装您的应用程序时,myapp
将在其路径中,lib
将在应用程序的加载路径中,因此您的可执行文件可以简单地以开头
#!/usr/bin/env ruby
require 'myapp'
# whatever other requires
唯一的问题是,在开发过程中,不能只执行bin/myapp
并运行应用程序。一些开发人员通过$:
或$LOAD_PATH
操作加载路径,但这被认为是不好的形式
如果您正在使用bundler,那么最简单的方法是使用bundle exec
(例如bundle exec bin/myapp
)在本地运行您的应用程序。您可以交替使用RUBYLIB
环境变量,例如RUBYLIB=lib bin/myapp
,它将把lib
放入加载路径中。
您可以使用Bundler生成一个gem项目结构。
简言之:
安装Bundler
$ gem install bundler
使用Bundler生成gem项目
$ bundle gem myapp
$ cd myapp
添加可执行文件
$ mkdir bin
$ cat > bin/mycommand << EOSCRIPT
#!/usr/bin/env ruby
require 'myapp'
puts "Executing myapp"
EOSCRIPT
$ chmod +x bin/mycommand
安装您的宝石
$ rake install
运行脚本
$ mycommand
Executing mycommand
在rubygems.org上分享您的实用程序
$ rake release
网站上的更多文档
由于所有gem本质上都是开源的,因此您可以查看一些更好的gem作为示例。使用像jeweler
或hoe
这样的gem构建器也可以从组织上为您设置一些基本结构。