创建你自己的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.