Rails支持多种方式的扩展,包括plugin,gem, 或者放到lib文件下等多种方式。 但是随着bundler的出现, Rails3时代我们还是写gem比较好, 方便管理。

所以下面只介绍如何制作属于自己的gem。开始之前先确保你机器了安装了git。

在我们的项目里面, 我看到在config/initializers/下有一个hash.rb文件, 是使用了一个monkey patch的方式来对Hash进行了一个扩展:

  class Hashdef # my_reversehash_new = Hash.newself.each {|key,value|if not hash_new.has_key?(key) then hash_new[value] = key end}return hash_newendend

像这种扩展方式不是很好, 我想把它修改为一个gem, 如果以后有其他的扩展,比如对Array,Hash等其他方法扩展,我们可以升级gem,这样就方便管理了,不至于那么混乱。

我们开始吧:
1. 安装bundler, 因为我要用bundler来生成一个基础gem结构。

          gem install bundler

2. 使用bundler来生成一个基础gem结构:

           bundle gem ruby_extendsions

命令执行以后会看到生成下面这些文件:

      create  ruby_extendsions/Gemfilecreate  ruby_extendsions/Rakefilecreate  ruby_extendsions/.gitignorecreate  ruby_extendsions/ruby_extendsions.gemspeccreate  ruby_extendsions/lib/ruby_extendsions.rbcreate  ruby_extendsions/lib/ruby_extendsions/version.rb
Initializating git repo in /Users/alex/work/mygems/test/ruby_extendsions

说明一下:
1). ruby_extendsions.gemspec , 类似于这样的.gemspec文件,就相当于gem的说明书, 将来你打gem包的时候, 就靠这个文件了。
2). lib下放我们的代码实现
3). 整个项目至于git版本控制下。方便我们push到rubygem.org.

3. 使用Rspec进行TDD方式开发我们的代码:
确保我们能用rspec, 在ruby_extendsions.gemspec里添加:

s.add_development_dependency "rspec"

然后,执行:

bundle install

这下我们就可以使用rspec了。
在根目录下增加一个spec文件夹, 考虑到我们要实现的功能, 是对ruby的一些扩展, 所以我暂时就命名为了ruby_extendsions, 而此次只是针对Hash类的扩展, 所以我们需要在spec目录下建立一个测试文件hash_spec.rb和spec_helper.rb来测试我们对Hash扩展功能是否正确:

#spec/hash_spec.rbrequire File.expand_path(File.dirname(__FILE__) + '/spec_helper')describe "RubyExtend::HashExtendsions" dobefore(:each) do@hash1 = {:a => 1, :b => 2}endit "A hash data should not be reversed if havn't use ruby_extend " do#当没有使用我们的扩展的时候, Hash类是不应该包含hash_reverse这个方法的, 这个测试也保证了我们在扩展一个Ruby内部类的时候不会和其内部方法名冲突。@hash1.respond_to?("hash_reverse").should eql false  endit "A hash data should be reversed" dorequire 'ruby_extendsions'@hash1.hash_reverse.should eql({1=>:a, 2=>:b} )end
end

上面的代码:spec_helper.rb文件为将来准备,如果扩展其他方法, 会用到一些公用的配置。
测试由一 个正例和一个反例组成。

4. 运行测试:

bundle exec rspec spec

, bundle exec确保rspec是使用我们在.gemspec文件里声明的版本。
当然,测试结果是会失败,因为我们还没有扩展hash_reverse方法呢。

5. 实现代码:
打开lib/ruby_extendsions.rb:

         require 'ruby_extendsions/hash_extendsions'   #我们今天要实现的Hash扩展require 'ruby_extendsions/array_extendsions'  #以后有可能用到对Array方法的扩展,我们就放这个文件里。
然后在lib下建立hash_extendsions.rb文件:
module RubyExtendsions      module HashExtendsions      #注意模块的命名要和文件名和路径保持一致。def self.included(base)     #hook, 当这个module在被include的时候触发base.send :include, InstanceMethods  #引入实例方法base.send :extend, ClassMethods          # 引入类方法endmodule InstanceMethodsdef hash_reverse   #我们的hash_reverse是实例方法hash_new = {}self.each {|key,value|if not hash_new.has_key?(key) then hash_new[value] = key end}return hash_newendend#InstanceMethodsmodule ClassMethods#TODOend#ClassMethodsend #HashExtendsions
end #RubyExtendsions#真正的扩展
class Hashinclude RubyExtendsions::HashExtendsions
end

上面的代码都带注释了。
然后我们运行测试, oK, 都通过了。大功告成了。

6. 发布我们的gem:
我们修改一下.gemspec文件, 把项目相关信息都写里面去:

# -*- encoding: utf-8 -*-Gem::Specification.new do |s|s.name        = "ruby_extendsions" s.version     = "0.1" s.platform    = Gem::Platform::RUBYs.authors     = ["blackanger"]s.email       = ["blackanger.z@gmail.com"]s.homepage    = "http://rubygems.org/gems/ruby_extendsions" s.summary     = "Ruby Extendsions For Hash" s.description = "Ruby Extendsions" s.required_rubygems_version = ">= 1.3.6" s.rubyforge_project         = "ruby_extendsions" s.add_development_dependency "bundler", ">= 1.0.0" s.add_development_dependency "rspec" s.files        = `git ls-files`.split("\n")s.executables  = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compacts.require_path = 'lib'
end
然后, 我们在根目录下执行命令:
rake install

这个命令会生成pkg/ruby_extendsions-0.1.gem. 到此为止,我们的gem包就打好了。

你可以把你的gem项目上传到github。 但是github从去年开始就停止了自动打包服务。所以你如果想使用gem install ruby_extendsions命令来安装你的gem, 需要把它上传到rubygems.org里。 
首先,你需要在rubygems.org里注册一个帐号。 
其次, gem install gemcutter
然后你就push吧。   gem push ruby_extendsions-0.1.gem
如果碰到权限的错误,那说明在rubygems里面已经有了和你一样名字的gem包,换个名字就oK了。

P.S 我的这个gem已经上传到了rubygems.org上面, 也上传到了github. (完整代码:http://github.com/ZhangHanDong/ruby_extend).

转载于:https://blog.51cto.com/blackanger/411334

如何制作自己的gem相关推荐

  1. 如何制作自己的CocoaPod库

    作者 OneTea 关注 2016.12.29 18:02* 字数 848 阅读 102评论 0喜欢 6 制作流程图: 流程图 1.将代码托管在github上 1.1本地代码 如图: Snip2016 ...

  2. fpm定制化RPM包之nginx rpm包的制作

    fpm定制化RPM包之nginx rpm包的制作 1.安装ruby模块 # yum -y install ruby rubygems ruby-devel 2.添加阿里云的Rubygems仓库,国外资 ...

  3. 使用fpm简单制作自定义rpm包

    我的环境是centos7.2的 一.安装FPM工具 yum -y install ruby rubygems ruby-devel gem sources list   查看gem包管理源仓库地址 g ...

  4. 组件化开发,制作Cocoapods Git库

    在项目中,如果项目功能很多而且工程浩大,需要多个技术部门或小组同时进行开发,根据独立功能模块进行分配.多个小组开发模块怎么样快速优雅的进行整合到主项目中呢?这个是时候组件化开发优势就体现出来了,每个模 ...

  5. fpm制作mysql rpm包_FPM简介(定制rpm包)

    FPM简介 fpm是生成rpm包的工具.rpm包的制作,采用fpm工具完成,FPM非常易用,此命令可以把rpm包的安装.卸载做得更加优雅,在安装前可以做一些准备工作,安装后可以做一些收尾工作,在卸载前 ...

  6. 制作Geek风格的投影片

    做投影片用什么?如果你的回答是用PowerPoint,有没有感觉弱爆了?好吧,也许你会说用开源的替代,比如openOffice/Libreoffice.当然其实本质都是一样的,那就是PPT! 从今天开 ...

  7. CentOS6.7上使用FPM打包制作自己的rpm包

    自定义rpm包,还是有逼格和实际生产环境的意义的. (下面的文档有的代码由于博客排版的问题导致挤在了一起,需要自己判别) 安装FPM fpm是ruby写的,因此系统环境需要ruby,且ruby版本号大 ...

  8. Centos7利用fpm制作rpm包(fpm安装及使用)

    安装fpm 安装ruby yum -y install ruby rubygems ruby-devel 查看当前ruby源 gem source -l 添加国内源,删除国外源 gem sources ...

  9. 小哥哥你有98K吗?利用Python制作一款多功能变声器!

    前言 好吧,关于这句小哥哥你有98K吗?出自别人口中经常说的玩笑话,我也略懂一些游戏嘛.不过不常玩,废话不多说,开始咱们今天的教程,非常简单! 利用Python制作一款多功能变声器! 咱们首先登陆百度 ...

最新文章

  1. android os开机画面,Android简单实现启动画面的方法
  2. java byter是字节吗_GitHub - XXQAQ/Byter: 字节对象转换框架,一个基于字节的 Gson/FastJson...
  3. Quartz.NET 架构与源代码分析系列 part 2 :Job 作业
  4. java 示例_功能Java示例 第4部分–首选不变性
  5. G1垃圾收集器设计目标与改良手段【纯理论】
  6. python 工具箱_Python交易工具箱:通过指标子图增强图表
  7. Socket实现Android客户端与服务器的通信
  8. Java 启动和停止界面_一文详解各种花里胡哨的Java调试技巧,多图预警,记得收藏...
  9. python时间模块哪个好arrow模块_Arrow-一个最好用的日期时间Python处理库
  10. 【白帽子讲Web安全】第一章 我的安全世界观
  11. KDE桌面下konsole打开terminal/tab 并执行命令或脚本
  12. python进程/线程/协成
  13. 东北大学《传输原理》随堂练习
  14. 2017普实软件迎新年会报道
  15. 【How2RE】 UPX壳及脱壳方式
  16. surface怎么将计算机放到桌面,笔者帮您win10系统把此电脑和控制面板在桌面上显示的妙计...
  17. windows 2003 下SERVU:无法开始服务器.服务器执行缺少
  18. 宝塔Linux面板——用正确的入口登录面板
  19. 程序人生 - 狗狗会“嫉妒”吗?
  20. C#项目实战——YModem协议文件传输【实例】

热门文章

  1. 11月下旬国内域名解析商Top10:中国数据5.03%居第四
  2. websocket python爬虫_python实现基于websocket协议的网络爬虫
  3. pandas官方文档_电影数据轻松学习 Pandas
  4. P1291 [SHOI2002]百事世界杯之旅
  5. bzoj4361 isn (dp+树状数组+容斥)
  6. jmeter的基本功能使用详解
  7. Deconvolution与Upsampling的区别
  8. Vue.js实现前段评论展示
  9. 软件测试技术lab2——Selenium上机实验
  10. 为什么我们有时不用配置java环境变量?