如何开发一个自己的 RubyGem?
「如何测试你的 RubyGem?」的前导文章
什么是 RubyGem
RubyGem 是 Ruby 语言的标准源码打包格式。
大家一直都在用gem这个命令,但是很少有人知道这个东西是怎么来的,这里我从网上扒下一些资料汇总一下,分享给大家。最后面会有这些链接,想进一步了解的,可以点进去看看。Ruby 语言深受其他几种脚本语言的影响,其中就有 Perl,而 Perl 有个 CPAN(Comprehensive Perl Archive Network),这个东西也就像是现在的 RubyGems.org ,但是当时 Ruby 是没有这样一个东西的。像 CPAN 和 RubyGem ,它们仅仅是定义好的一种源码的打包和安装方式,另外还有一些组织,会提供这种免费的公共的源码包的存储,这也就现在大家每天都要使用的安装方式:
gem install rails
在 RubyGem 的发展历史当中,有几位重要的人物,这里也作为八卦知识给大家晒一晒,就当做大家茶余饭后的谈点吧。Ruby 社区的人应该都知道 Jim Weirich 这个人,他已经在2014年2月份去世了,是一个可爱的白胡子大叔,他和另外的四位 Rich Kilmer, Chad Fowler, David Black, Paul Brannan在2003年制定了 RubyGem 的基本规范和实现,但是其实 RubyGem 最早是 Ryan Leavengood 在2001年开发的,可惜没有流行起来,最后到了2003年,前面的5个人经过 Ryan Leavengood 的同意,使用了 RubyGem 这个名称,开发了新版的 RubyGem,其中并没有使用 Ryan Leavengood 的代码。这里附上 rubygems 的执行文件链接,看看注释,里面有上面几个人的名字 rubygems/blob/master/bin/gem
rubygems 有默认的源,也可以更改,国内的基本就是 https://rubygems.taobao.org 了,有些公司有自己的需求,也会搭建自己的私源。当前的官方源为https://rubygems.org,这个源也是几经辗转,早期的 Ruby 用户都知道 http://gems.rubyforge.org和http://gemcutter.org,甚至github都曾经作为源使用过,也就是 http://gems.github.com,这三个现在都已经弃用了。
看看,一个简单的gem install 历史还不少啊。
RubyGem 的基本使用方法
gem install rails //安装rails
gem install rails -v 4.2.0 //安装指定版本的rails
gem search rails //查找所有名称中含有rails的gem
gem search ^rails //查找所有名称中以rails开头的gem
gem search ^rails -d //查找所有名称中以rails开头的gem,并显示描述
gem build package.gemspec //构建一个gem,就是把你自己写的gem源码,打包成一个.gem文件
gem push pack-1.0.gem //发布到源上,默认是rubygems.org
这里只是简单列出了最常用的使用方法,大家看看就好,命令很有限,也很简单,执行gem --help,基本上所有的东西你都能10分钟内学会。
如何制作一个自己的 RubyGem
前几年还是有这样那样的工具,现在用bundler就够了。
$ bundler gem mygem
create mygem/Gemfile
create mygem/Rakefile
create mygem/LICENSE.txt
create mygem/README.md
create mygem/.gitignore
create mygem/mygem.gemspec
create mygem/lib/mygem.rb
create mygem/lib/mygem/version.rb
Initializing git repo in /home/lizhe/Workspace/mygem
一个bundler命令就搞定了。来看看mygem这个文件夹下的东西:
total 24
-rw-rw-r-- 1 lizhe lizhe 90 7月 2 15:52 Gemfile
drwxrwxr-x 3 lizhe lizhe 4096 7月 2 15:52 lib
-rw-rw-r-- 1 lizhe lizhe 1062 7月 2 15:52 LICENSE.txt
-rw-rw-r-- 1 lizhe lizhe 850 7月 2 15:52 mygem.gemspec
-rw-rw-r-- 1 lizhe lizhe 29 7月 2 15:52 Rakefile
-rw-rw-r-- 1 lizhe lizhe 556 7月 2 15:52 README.md
现在来看看gemspec这个文件,它描述了这个Gem的各种信息
# coding: utf-8
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 = ["lizhe"]
spec.email = ["lizhe@oneapm.com"]
spec.summary = %q{TODO: Write a short summary. Required.}
spec.description = %q{TODO: Write a longer description. Optional.}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
end
我发现有人看到这个文件的内容时,倒是关心那个'git ls-files -z'.split("\x0")是什么意思?以及那个\x0是什么?附上一个链接,解释一下,参考链接。这个文件最上面先把 lib 文件夹添加到 load path 中,Gem::Specification 的第一部分主要是描述这个 gem 的信息,包括名称,版本等等,第二部分是这个 gem 都包括哪些文件,执行文件,测试文件以及哪些路径下的文件可以添加到 load path 中。第三部分是开发 mygem 需要依赖的其他 gem。这些信息都可以自定义,先按照默认走。让我们 build 第一个 gem 吧。
$ rake build
rake aborted!
WARNING: See http://guides.rubygems.org/specification-reference/ for help
ERROR: While executing gem ... (Gem::InvalidSpecificationException)
"FIXME" or "TODO" is not a description
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:149:in `sh'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:57:in `build_gem'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:39:in `block in install'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/bin/ruby_executable_hooks:15:in `eval'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => build
(See full trace by running task with --trace)
这个警告是提醒我们需要替换gemspec中的FIXME和TODO,这个警告如果不解决是无法 build 一个 gem 的,直接删除掉 summary 和 description 中的TODO:
spec.summary = %q{Write a short summary. Required.}
spec.description = %q{Write a longer description. Optional.}
再来执行:
$ rake build
mygem 0.0.1 built to pkg/mygem-0.0.1.gem.
好了,第一个 gem 诞生了。它就在当前目录的 pkg 下: mygem-0.0.1.gem 。如何使用呢?不考虑 bundler 的情况下,如果你开起了一个 irb 或者 pry 的 session 时,一般都会这样写:require "mygem",如果你现在这样做,那肯定不行,因为它还没有被安装到 ruby 的 load path 中,那就把它安装上。
$ rake install
mygem 0.0.1 built to pkg/mygem-0.0.1.gem.
mygem (0.0.1) installed.
安装好了,那就来使用一下,打开 irb :
require "mygem"
=> true
Mygem
=> Mygem
看,已经可以使用这个 module 了,不过这个 gem 啥也干不了,那么我们就给它添加一个方法吧,打开 lib/mygem.rb ,添加一个方法:
require "mygem/version"
module Mygem
def self.hello
p "hello from my gem"
end
end
保存,然后执行rake install,这个命令会先 build 然后 install ,再重新打开 irb :
require "mygem"
=> true
Mygem.hello
=> "hello from my gem"
能够正常运行了,那就来发布第一个 gem 吧:
rake release
// 输入你在rubygems.org上的账号和密码
如果你的一个 rails 应用正好需要输出一个hello from my gem,那么现在你可以在 Gemfile 中添加这个 gem 了:
gem 'mygem'
添加完执行 bundle install,你就可以在你的 rails 应用中使用它了。
参考链接:
本文系 OneAPM 工程师李哲原创文章。请访问OneAPM 官方技术博客。
如何开发一个自己的 RubyGem?的更多相关文章
- 拥抱.NET Core,如何开发一个跨平台类库 (1)
在此前的文章中详细介绍了使用.NET Core的基本知识,如果还没有看,可以先去了解“拥抱.NET Core,学习.NET Core的基础知识补遗”,以便接下来的阅读. 在本文将介绍如何配置类库项目支 ...
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- [MEF插件式开发] 一个简单的例子
偶然在博客园中了解到这种技术,顺便学习了几天. 以下是搜索到一些比较好的博文供参考: MEF核心笔记 <MEF程序设计指南>博文汇总 先上效果图 一.新建解决方案 开始新建一个解决方案Me ...
- bootstrap开发一个简单网页。
CSS代码: body{ padding-top: 50px; padding-bottom: 50px; overflow: auto!important; ...
- 后移动互联网时代:到底还要不要开发一个App?
后移动互联网时代,到底是什么样的一个时代? 首先,后移动互联网时代中,产生头部应用的几率变小了,像微信这样巨头式的App很难在产生第二个.其次,后移动互联网时代,物联网发展迅速,所有的智能硬件都需要一 ...
- iOS开发一个用户登录注册模块需要解决的坑
最近和另外一位同事负责公司登录和用户中心模块的开发工作,开发周期计划两周,减去和产品和接口的协调时间,再减去由于原型图和接口的问题,导致强迫症纠结症状高发,情绪不稳定耗费的时间,能在两周基本完成也算是 ...
- 【如何快速的开发一个完整的iOS直播app】(美颜篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重 ...
- 【如何快速的开发一个完整的iOS直播app】(采集篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,首先需要采集主 ...
- 【如何快速的开发一个完整的iOS直播app】(播放篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看上篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,集成ijkpl ...
随机推荐
- Python核心编程--学习笔记--6--序列(上)字符串
本章研究Python中的序列:字符串.列表和元组.因为这些类型其实都是由一些成员共同组成的一个序列整体,所以我们把它们统称为序列.序列的存储结构可以表示为: 1 序列 序列类型有着相同的访问模式:按下 ...
- ASP.NET浏览器定义文件及IE兼容模式
由于ASP.NET4.0中的一个小bug,导致了ASP.NET WebForms控制的CallBack无效,部分控件无法使用. 解决方法是在项目中添加自定义的浏览器定义文件,参考这里:http://w ...
- WIN服务器出现 php-cgi.exe - FastCGI 进程意外退出
既然是不能解析PHP,那就直接运行一下PHP,看会报什么错,再对症下药,于是,在命令提示符窗口进入php安装的根目录,然后运行php -v的命令,这时窗口弹出计算机丢失msvcr110.dll的错误, ...
- 【转】Git常用命令备忘
Git配置 git config --global user.name "robbin" git config --global user.email "fankai@g ...
- 【linux命令系列】熟练运用每一个光标移动到最前和最后
ctrl+e?a和e ahead 和 end 看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下 ...
- How to write a windows service
how to write a windows services susport microsoft This aritcle describe the detail step to setup a w ...
- perl连接mysql(转载)
文章来源:http://blog.sina.com.cn/s/blog_9d0445d50101czsr.html 首先需要用ppm安装DBI和DBD-mysql ,如果没有的话点击EDIT-pref ...
- mini6410-JNI-led
一.编写JNI模块 当安装好NDK编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块. 1.在/home/android/文件夹下,新建“ledjni ...
- SDOI2016 round1滚粗记
Day -1 刚刚从HN集训回来,感觉整个人萌萌哒.考前不断立flag——这次我一定会滚粗的,然后设想着滚粗之后文化课先补什么,浑浑噩噩的过了一天,晚上看到CA爷(娘)发了关于cena爆栈的问题,这时 ...
- 设计模式 -- 单例模式(Java&&PHP)
所谓单例模式,简单来说,就是在整个应用中保证只有一个类的实例存在.就像是Java Web中的application,也就是提供了一个全局变量,用处相当广泛,比如保存全局数据,实现全局性的操作等. 能够 ...