gem详解

1. 执行命令,创建一个gem,rand_t就是你gem的名字,命名规范

1
bundle gem rand_t

执行完成之后,会生成如下文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MIT License enabled in config
Code of conduct enabled in config
create rand_t/Gemfile
create rand_t/.gitignore
create rand_t/lib/rand_t.rb
create rand_t/lib/rand_t/version.rb
create rand_t/rand_t.gemspec
create rand_t/Rakefile
create rand_t/README.md
create rand_t/bin/console
create rand_t/bin/setup
create rand_t/LICENSE.txt
create rand_t/CODE_OF_CONDUCT.md
Initializing git repo in /Users/tlt/gems/rand_t

bin路径下的两个文件是可执行文件

  • bin/setup相当于执行bundle install
  • bin/console 会加载rand_t,并进入irb模式,方便调试

lib路径下的文件,是我们的主目录

  • 其中 rand_t.rb 是我们的入口文件,当其他程序 require ‘rand_t’ 的时候,这个文件会被加载。
    入口文件 rand_t.rb 是为了加载 gem的依赖,这些依赖可以是内部的类,也可以是第三方的库。
  • rand_t文件夹下,是我们要实现功能代码的地方 LICENSE.txt 许可证

README.md 是我们的gem使用文档

Rakefile 引用这个库,可以让我们使用一些内置的rake任务来发布gem

1
require "bundler/gem_tasks"

.gitignore git忽略文件

rand_t.gemspec 官方文档前两行把gem的lib目录加载到 load path(ruby会寻找的额外库的path),这会允许我们从宿主调用‘rand_t’
Gem::Specification定义了一些我们gem的基本信息,名称、作者、邮箱、主页、用途等。

allowed_push_host是可以发布此gem的地址。

files是指定打包的文件

bindir和executables 指定可执行文件路径

add_development_dependency 开发环境加载的依赖

add_dependency 所有环境都加载

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
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'rand_t/version'
Gem::Specification.new do |spec|
spec.name = "rand_t"
spec.version = RandT::VERSION
spec.authors = ["tianlitao"]
spec.email = ["tianlitao3399@gmail.com"]
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."
spec.license = "MIT"
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
# to allow pushing to a single host or delete this section to allow pushing to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
else
raise "RubyGems 2.0 or newer is required to protect against " \
"public gem pushes."
end
spec.files = `git ls-files -z`.split("\x0").reject do |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.13"
spec.add_development_dependency "rake", "~> 10.0"
end

Gemfile gemspec方法表明了bundler会从 rand_t.gemspec 文件去定义 gem 的依赖

2. 添加我们自己的代码

在lib/rand_t下新建 gen_num.rb,添加代码

1
2
3
4
5
6
7
8
9
10
11
12
module RandT
module GenNum
def self.gen
5.times.map{ single_draw }
end
private
def single_draw
rand(0...60)
end
end
end

3. 生成gem文件

1
gem build rand_t.gemspec

4. 发布gem

1
gem push rand_t-0.1.0.gem