Gem介绍

Gem是Ruby源代码库的打包格式,其内部有以下组件

  • 源代码(包括测试和工具代码)
  • 文档
  • gemspec

其中gemspec中描述了Gem的名字,版本,平台,依赖等信息。它也是由Ruby编写。

手动创建一个Gem,官方教程已经写的很明白了,最后写好的Gem的目录结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ tree
.
├── Rakefile # Rake的构建文件
├── bin # Gem的可执行文件
│ └── hola
├── hola-0.0.0.gem
├── hola.spec # Gem的描述文件
├── lib # 源代码主要目录
│ ├── hola # 二级引入的目录
│ │ └── translator.rb # 使用时对应 require 'hola/translator'
│ └── hola.rb # 使用时直接require 'hola'时引入的文件
└── test # Gem的测试目录
└── test_hola.rb

4 directories, 7 files

使用bundler管理Gem

生成Gem模版

使用bundler 工具可以快速的生成一个Gem的模版

1
$ bundle gem mygem

生成的目录结构和上文一致,gemspec文件的描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "mygem/version"

Gem::Specification.new do |spec|
spec.name = "mygem"
spec.version = Mygem::VERSION
spec.authors = ["jeffery"]
spec.email = ["[email protected]"]

spec.summary = %q{TODO: Write a short summary, because RubyGems requires one.}
spec.description = %q{TODO: Write a longer description or delete this line.}
spec.homepage = "TODO: Put your gem's website or public repo URL here."

if spec.respond_to?(:metadata)
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
else
raise "RubyGems 2.0 or newer is required to protect against " \
"public gem pushes."
end

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 1.16"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "minitest", "~> 5.0"
end

在文件中spec的字段描述了的Gem基本信息,除了文件中这些字段,其他的字段参考链接

文件中的spec.files字段,是当前Gem源代码的所有文件列表(而不是目录),所以使用了git ls-files -z命令,最后把返回的字符串通过String#split方法拆分成了列表。详细解释参考链接

编写代码

在lib中的mygem.rb中:

1
2
3
4
5
6
7
require "mygem/version"

module Mygem
def self.hello
puts "hello world"
end
end
编译Gem

使用Rake命令build Gem。Rake意思为Ruby Make,一个用ruby开发的代码构建工具。

1
2
$ rake build
mygem 0.1.0 built to pkg/mygem-0.1.0.gem.

在pkg目录下的mygem-0.1.0.gem就是生成好的Gem文件,然后在把它安装到Gem的本地目录中去,使用

1
2
3
$ rake install
mygem 0.1.0 built to pkg/mygem-0.1.0.gem.
mygem (0.1.0) installed.

使用gem命令查看是否安装成功

1
2
$ gem list --local | grep "mygem"
mygem (0.1.0)

接下来就可以在pry或者irb中使用了

1
2
3
4
require "mygem"
=> true
Mygem.hello
=> "hello world"

编写完之后还可以使用rake release发布Gem到rubygems.org

参考链接