创建你自己的gem
make your own gem
- Introduction
- Your first gem
- Requiring more files
- Adding an executable
- Writing tests
- Documenting your code
- Wrapup
介绍
通过rubygem内置的工具就能够轻松的打包代码为gem.让我们来创建一个简单的hello world
的gem.
第一个gem
创建一个名为hola的gem.还有一个gemspec,目录结构如下:
-hola.gemspec
`--lib
`--hola.rb
其实关键的你代码是放在lib文件夹里面的,有一个约定就是要有一个和你的gem名称一样的ruby文件.
这样的话,就可以直接通过require 'hola'
来引用此gem了.此文件就是gem的入口.
看看在lib/hola.rb
的内容:
class Hola
def self.hi
puts "Hello world!"
end
end
下面来看一些gemspec文件里定义了什么内容,其他不外乎就是谁写的,版本,依赖等.
Gem::Specification.new do |s|
s.name = 'hola'
s.version = '0.0.0'
s.date = '2010-04-28'
s.summary = "Hola!"
s.description = "A simple hello world gem"
s.authors = ["Nick Quaranto"]
s.email = 'nick@quaran.to'
s.files = ["lib/hola.rb"]
s.homepage =
'http://rubygems.org/gems/hola'
s.license = 'MIT'
end
看着眼熟?其实就是ruby代码了.
关于到底有什么能够放在里面,可以参照这里.
创建gemspec之后,就可以build一个gem 了.之后就可以安装build之后的gem了.
通过此命令
gem build hola.gemspec
你可以看见如下的控制台输出:
Successfully built RubyGem
Name: hola
Version: 0.0.0
File: hola-0.0.0.gem
% gem install ./hola-0.0.0.gem
Successfully installed hola-0.0.0
1 gem installed
当然要确保能够使用,还需实际的使用它啊,通过reuqire
irb
require ‘hola’
true
Hola.hi
可以看见输出hello world了.那就表示成功了一大步.之后就可以准备发布到rubygem了.
首先要配置登录到rubygem的信息:
> curl -u yourusername_on_rubygem
https://rubygems.org/api/v1/api_key.yaml >
~/.gem/credentials; chmod 0600 ~/.gem/credentials
Enter host password for user 'yourusername_on_rubygem':
如果系统限制等,无法使用curl,openssl等,可以通过浏览器访问链接`https://rubygems.org/api/v1/api_key.yaml`,它会让你登录的,
成功则会下载一个认证信息文件`api_key.yaml`,完了直接把它放到~/.gem/文件夹下,重命名为**credentials**
一切设置妥当之后,就可以push你的gem了
gem push hola-0.0.0.gem
Pushing gem to RubyGems.org...
Successfully registered gem: hola (0.0.0)
上传过一会儿你就可以通过下面命令check到你的gem了:
gem list -r hola
然后尝试安装:
gem install hola
一切OK~
我们来个复杂点的
修改lib/hola.rb
class Hola
def self.hi(language = "english")
translator = Translator.new(language)
translator.hi
end
end
class Hola::Translator
def initialize(language)
@language = language
end
def hi
case @language
when "spanish"
"hola mundo"
else
"hello world"
end
end
end
上面的代码已经很拥挤了.我们把Translator
这个类拆分到单独的文件中,之前提到的是把所有的ruby文件都放到lib
目录. 我们可以把目录结构调整成下面的样子:
├── hola.gemspec
└── lib
├── hola
│ └── translator.rb
└── hola.rb
之后在原来lib/hola.rb的文件需要修改一下:
require 'lib/translator'
class Hola
def self.hi(language = "english")
translator = Translator.new(language)
translator.hi
end
end
接着还要修改一下gemspec文件,把新添加的目录和文件索引进去,不然到时候打包的时候新文件不会被打包进去:
...
s.files = ["lib/hola.rb", "lib/hola/translator.rb"]
...
添加一个可执行的文件
gem不仅仅只是提供一些ruby code. 同时还暴漏了一些可执行的文件到你当前的shell目录下.如rake
. 还有一个比较有趣的工具就是
prettify_json.rb
,包含在json的gem包,它能够用来format输出json.
curl -s http://jsonip.com/ |
prettify_json.rb
{
"ip": "24.60.248.134"
}
其实往gem里添加可执行的文件也很简单.把他们放到bin/
目录.然后在gemspec里添加他们.让我们继续在hola的gem里修改:
% mkdir bin
% touch bin/hola
% chmod a+x bin/hola
这个bin/hola
文件第一行要添加#!
来告诉机器用什么目录执行它.
#!/usr/bin/env ruby
require 'hola'
puts Hola.hi(ARGV[0])
之后在gemspec文件里添加可执行的文件配置说明:
s.name = 'hola'
s.version = '0.0.1'
s.executables << 'hola' #可执行文件
编写测试
测试自己的gem非常重要,不仅仅是确保自己的代码能够工作,而且能够帮助别人.很多人通过测试用例的质量来衡量
代码质量.gem支持如果在gem里有测试的话在下载完之后自动执行测试的功能.
TEST YOUR GEM!
TEST::Unit
是ruby内置的测试框架,有很多的教程在网上可以找到.同样还有很多其他的测试框架如RSpec
.
不管怎么样,我们来添加测试吧.
首先创建文件Rakefile
和文件夹test
:
.
├── Rakefile
├── bin
│ └── hola
├── hola.gemspec
├── lib
│ ├── hola
│ │ └── translator.rb
│ └── hola.rb
└── test
└── test_hola.rb
编辑test_hola.rb
:
require 'test/unit'
require 'hola'
class HolaTest < Test::Unit::TestCase
def test_english_hello
assert_equal "hello world",
Hola.hi("english")
end
def test_any_hello
assert_equal "hello world",
Hola.hi("ruby")
end
def test_spanish_hello
assert_equal "hola mundo",
Hola.hi("spanish")
end
end
在Rakefile
里添加一些简单的测试test task:
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs << 'test'
end
desc "Run tests"
task :default => :test
之后执行rake test
或者直接rake
来执行测试:
% rake test
(in /Users/qrush/Dev/ruby/hola)
Loaded suite
Started
...
Finished in 0.000736 seconds.
3 tests, 3 assertions, 0 failures, 0 errors, 0 skips
Test run options: --seed 15331
you made it!
文档
大部分的gem会使用默认内建RDoc来生成文档.有很多的教程可以学习.
# The main Hola driver
class Hola
# Say hi to the world!
#
# Example:
# >> Hola.hi("spanish")
# => hola mundo
#
# Arguments:
# language: (String)
def self.hi(language = "english")
translator = Translator.new(language)
puts translator.hi
end
end
结尾
至此已经完成了一个简单的gem,很多东西需要继续学习深究,ENJOY IT!
Written with StackEdit.