RubyGems是一個(gè)庫和程序的標(biāo)準(zhǔn)化打包以及安裝框架,它使定位、安裝、升級(jí)和卸載Ruby包變的很容易。rails以及它的大部分插件都是以gem形式發(fā)布的。本文描述一個(gè)自己創(chuàng)建ruby Gems的過程。
假設(shè)你今天用ruby實(shí)現(xiàn)了一個(gè)stack結(jié)構(gòu),你想發(fā)布到網(wǎng)上讓別人可以共享,OK,工作開始了。首先你的程序當(dāng)然要先寫好了:
#stacklike.rb
module Stacklike
attr_reader:stack
def initialize
@stack=Array.new
end
def add_to_stack(obj)
@stack.push(obj)
end
def take_from_stack
@stack.pop
end
def size
@stack.length
end
alias length size
def clear
@stack.clear
end
end
然后就是我們的Stack類,引入這個(gè)Module,請(qǐng)注意,我們這里只是特意這樣做,增加點(diǎn)復(fù)雜度:
#stack.rb
require 'stacklike'
class Stack
include Stacklike
end
作為一個(gè)要被大眾使用的小程序,一定要有完備的測(cè)試代碼,OK,ruby內(nèi)置了單元測(cè)試庫,我們來寫個(gè)單元測(cè)試來測(cè)試Stack:
require 'stack'
require 'test/unit'
class TestStack <Test::Unit::TestCase
def testStack
stack=Stack.new
assert_equal(0,stack.size)
assert_equal(stack.length,stack.size)
stack.add_to_stack(1)
assert_equal(1,stack.length)
assert_equal(1,stack.take_from_stack)
stack.clear
assert_equal(0,stack.length)
assert_nil(stack.take_from_stack)
10.times{|i| stack.add_to_stack(i)}
assert_equal(10,stack.size)
assert_equal(stack.length,stack.size)
9.downto(4){|i| assert_equal(i,stack.take_from_stack)}
assert_equal(4,stack.length)
assert_equal(3,stack.take_from_stack)
assert_equal(3,stack.length)
stack.clear
assert_equal(0,stack.length)
assert_nil(stack.take_from_stack)
end
end
如果你使用radrails或者RDT運(yùn)行這段代碼,你將看到讓人舒服的greenbar,一切正常。程序?qū)懞昧耍酉聛砭褪顷P(guān)鍵步驟了,怎么發(fā)布成ruby Gems呢?
第一步,寫Gems規(guī)范文件 gemspec是ruby或者YAML形式的元數(shù)據(jù)集,用來提供這個(gè)gem的關(guān)鍵信息,我們創(chuàng)建一個(gè)文件夾就叫stack,然后在下面建立2個(gè)目錄兩個(gè)文件:
lib目錄:用于存放庫的源代碼,比如這個(gè)例子中的stack.rb,stacklike.rb
test目錄:用于存放單元測(cè)試代碼。
README文件:描述你的庫的基本信息和版權(quán)許可證等
stack.gemspec:gems規(guī)范文件,用以生成gem
當(dāng)然,也可以有docs目錄用以存放rdoc文檔和ext目錄用以存放ruby擴(kuò)展,我們這個(gè)簡(jiǎn)單例子就免了。
看看我們的規(guī)范文件:
#stack.spec
require 'rubygems'
SPEC=Gem::Specification.new do |s|
s.name="Stack"
s.version='0.01'
s.author='dennis zane'
s.email="killme2008@gmail.com"
s.homepage="http://www.rubyeye.net"
s.platform=Gem::Platform::RUBY
s.summary="ruby實(shí)現(xiàn)的Stack"
condidates =Dir.glob("{bin,lib,docs,test}/**/*")
s.files=condidates.delete_if do |item|
item.include?("CVS")|| item.include?("rdoc")
end
s.require_path="lib"
s.autorequire='stack,stacklike'
s.test_file="test/ts_stack.rb"
s.has_rdoc=false
s.extra_rdoc_files=["README"]
end
很明顯,規(guī)范文件也是ruby程序(也可以用YAML描述),設(shè)置了這個(gè)gem的主要關(guān)鍵信息:名稱、作者信息、平臺(tái),需要注意的就是files數(shù)組過濾掉了cvs和rdoc文件,require_path和auto_require讓你指定了require_gem裝入gem時(shí)會(huì)被添加到$LOAS_PATH(ruby查找?guī)斓穆窂剑┲械哪夸洠ㄒ簿褪俏覀冊(cè)创a存放的lib),auto_require指定了裝載的文件名,我們沒有rdoc,所有設(shè)置has_rdoc為false,附帶文檔就是README。
第二步 修改單元測(cè)試文件引用路徑過去我們假設(shè)ts_stack.rb與stack.rb、stacklike.rb在同一個(gè)目錄下,可是我們現(xiàn)在將它們分別放在lib和test目錄,TestStack
怎么引用測(cè)試的類呢?答案是在ts_stack.rb開頭加上一行:
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
最后一步 構(gòu)建gem在stack目錄執(zhí)行下列命令:
ruby stack.gemspec
或者:
gem build stack.gemspec
將生成一個(gè)文件,你可以將這個(gè)文件共享給朋友們咯。你的朋友只要下載這個(gè)文件,執(zhí)行:
gem install Stack.0.01.gem
將在他們的ruby環(huán)境中安裝你寫的stack,比較遺憾的是,你這個(gè)stack確實(shí)太簡(jiǎn)陋了,哈哈。