`

rubygems.org guides 翻译八(Patterns)

    博客分类:
  • gem
阅读更多

目录

1.命名一致性

2.版本语义化

3.声明依赖

4.加载代码

5.preRelease gem

 

一、命名一致性

There are only two hard things in Computer Science: cache invalidation and naming things. -Phil Karlton

1.文件名

保持lib和bin目录下文件命名的一致性。

hola gem的命名如下:

% tree
.
├── Rakefile
├── bin
│   └── hola
├── hola.gemspec
├── lib
│   ├── hola
│   │   └── translator.rb
│   └── hola.rb
└── test
    └── test_hola.rb

可执行文件和lib下的主文件命令相同。开发者可以轻易的使用require 'hola'来加载。

2.命名你的gem

命名自己的gem非常重要。在你命名你的gem之前,到on RubyGems.org and GitHub 搜索下,看看别人是否已经使用了这个名字。每一个发布的gem都必须使用一个唯一的名字。当你想好自己gem的名字时,请阅读 naming recommendations

 

二、版本语义化

版本控制策略只是一个版本如何被分配的简单规则。它非常简单(例如从1自增),或者非常特别(Knuth’s TeX 项目的 version numbers: 3, 3.1, 3.14, 3.141, 3.1415; each successive version added another digit to PI)

RubyGems团队使用语义化版本号来给gem规定版本。RubyGems并未严格强调命名策略,但是使用不合理的命名策略是在给其他使用你gem的人帮倒忙。

假设你有一个stack的gem,Stack class里面包含push和pop两个方法。如果你使用语义化版本控制,那么你的CHANGELOG需要像这样:

Version 0.0.1: The initial Stack class is released.
Version 0.0.2: Switched to a linked list implementation because it is cooler.
Version 0.1.0: Added a depth method.
Version 1.0.0: Added top and made pop return nil (pop used to return the old top item).
Version 1.1.0: push now returns the value pushed (it used it return nil).
Version 1.1.1: Fixed a bug in the linked list implementation.
Version 1.1.2: Fixed a bug introduced in the last fix.

语义化版本控制归结如下:

PATCH 0.0.x level changes for implementation level detail changes, such as small bug fixes
MINOR 0.x.0 level changes for any backwards compatible API changes, such as new functionality/features
MAJOR x.0.0 level changes for backwards incompatible API changes, such as changes that will break existing users code if they update

 

 

三、声明依赖

gem可以喝其他gem一起协同工作。下面是一些tips以确保他们之前正常工作。

1.运行时 vs 开发

rubygems提供两种类型的依赖:运行时和开发。运行时依赖是你的gem工作时所需要的(例如such as rails needing activesupport

开发时依赖对于别人想修改你的gem时非常有用。当你指定开发时依赖,其他开发者可以使用install --dev your_gem命令,rubygems会同时抓取两种依赖。典型的开发时依赖就是测试框架和构建系统。

在gemspec中设置依赖非常简单。只需要使用add_runtime_dependency and add_development_dependency

Gem::Specification.new do |s|
  s.name = "hola"
  s.version = "2.0.0"
  s.add_runtime_dependency "daemons",
    ["= 1.1.0"]
  s.add_development_dependency "bourne",
    [">= 0"]

2.不要在你得gem中使用gem

你也许有像下面一样的这些代码,确保你指定了gem的版本。

gem "extlib", ">= 1.0.8"
require "extlib"

对于应用来说,这样做有理由说是在consume gems(虽然他们也可能使用其他工具,例如 Bundler).gems本身不会这样做。他们会在gemspec中使用依赖,这样rubygems可以加载它,而不是用户自己去加载。

It’s reasonable for applications that consume gems to use this (though they could also use a tool like Bundler). Gems themselves should not do this. They should instead use dependencies in the gemspec so RubyGems can handle loading the dependency instead of the user.

3.封闭式的版本约束

如果你的gem版本计划遵循语义化版本2.0.0(http://semver.org/lang/zh-CN/),那么其他ruby开发者将会大受裨益,当他们在自己的应用中使用版本约束锁定gem的时候。
看看下面这样的gem版本releases
  • Version 2.1.0 — Baseline
  • Version 2.2.0 — Introduced some new (backward compatible) features.
  • Version 2.2.1 — Removed some bugs
  • Version 2.2.2 — Streamlined your code
  • Version 2.3.0 — More new features (but still backwards compatible).
  • Version 3.0.0 — Reworked the interface. Code written to version 2.x might not work.
某个其他使用你gem的人发现2.2.0在他的应用中工作良好,但是2.1.0不工作。那么他的gem配置,或者Gemfile(使用bundler)配置如下
# gemspec
spec.add_runtime_dependency 'library',
  '>= 2.2.0'

# bundler
gem 'library', '>= 2.2.0'
 
这是一个好的版本约束。他表示所有2.X版本的在我的应用中工作良好,但是3.X的不确定。
The alternative here is to be “pessimistic”. This explicitly(明白地)excludes(排除) the version that might break your code.
# gemspec
spec.add_runtime_dependency 'library',
  ['>= 2.2.0', '< 3.0']

# bundler
gem 'library', '>= 2.2.0', '< 3.0'
 
RubyGems 提供了一种简单的方式,叫做 twiddle-wakka:
# gemspec
spec.add_runtime_dependency 'library',
  '~> 2.2'

# bundler
gem 'library', '~> 2.2'
 
注意:他会抛弃补丁级别的版本号。
这里的~>2.2.0是指在[">=2.2.0", "<2.3.0"]这个区间。
If you want to allow use of newer backwards-compatible(向下兼容) 版本 but need a specific bug fix you can use a compound requirement:
# gemspec
spec.add_runtime_dependency 'library', '~> 2.2', '>= 2.2.1'

# bundler
gem 'library', '~> 2.2', '>= 2.2.1'
 
The important note to take home here is to be aware others will be using your gems, so guard yourself from potential bugs/failures in future releases by using ~> instead of >= if at all possible.
小提示:如果你不得不在你的应用中处理大量的gem依赖,那么我建议你看看bundler和isolate这样的工具,他会帮助你管理复杂的gem依赖问题。
If you want to allow prereleases and regular releases use a compound requirement:
# gemspec
spec.add_runtime_dependency 'library', '>= 2.0.0.a', '< 3'
 
在prerelease版本中使用~>限制你只能使用的prerelease版本。
4.require rubygems

摘要:不要。

这一行。。。。。。

require 'rubygems'

 

没必要出现在你的gem代码中,当一个gem required的时候,RubyGems 已经被加载了。

require 'rubygems'意味着这个gem使用简单,没必要运行RubyGems 客户端。

关于这个主题,如果你想了解更多,请查看 Ryan Tomayko

四、加载代码

从其核心,RubyGems的存在时帮助你管理ruby的$LOAD_PATH,他关系到require语句怎样加载你的代码。有几个方法可以使你确定你正确的加载了代码。

1.respect the global load path

当打包你的gem的时候,你需要特别注意你的lib目录里面是些什么。你安装的每一个gem都会把lib目录添加到你的$LOAD_PATH中去。这意味着lib目录中的顶层文件将会被加载。

例如,我们的foo这个gem有如下的目录结构:

 

.
└── lib
    ├── foo
    │   └── cgi.rb
    ├── erb.rb
    ├── foo.rb
    └── set.rb
 

 

这看上去你把自定义的erb和set文件放在这里是无害的。但这确实是有害的,每一个加载这个gem的用户就不能从ruby的标准库中加载erb和set了。避免这个的最好办法是在lib目录下使用其他目录。通常的做法是把他们放在和你的gem name同名的目录下。例如lib/foo/cgi.rb.

 

2.requiring files relative each other

Gems不应该使用__FILE__来加载其他文件到你的gem中。如下代码出人意料的普遍:

 

require File.join(
          File.dirname(__FILE__),
          "foo", "bar")

# or
require File.expand_path(File.join(
          File.dirname(__FILE__),
          "foo", "bar"))
 

 

The fix is simple,, just require the file relative to the load path:

 

require 'foo/bar'

#or 使用require_relative
require_relative 'foo/bar'
 

 

The make your own gem guide has a great example of this behavior in practice, including a working test suite. The code for that gem is on GitHub as well.

 

3.mangling the load path

gems不应该改变$_LOAD_PATH常量。RubyGems 帮你管理这些。如下代码是必须的:

 

lp = File.expand_path(File.dirname(__FILE__))
unless $LOAD_PATH.include?(lp)
  $LOAD_PATH.unshift(lp)
end

# or
__DIR__ = File.dirname(__FILE__)

$LOAD_PATH.unshift __DIR__ unless
  $LOAD_PATH.include?(__DIR__) ||
  $LOAD_PATH.include?(File.expand_path(__DIR__))
 

 

当RubyGems激活一个gem,退添加lib目录到你的 $LOAD_PATH 以准备好被其他lib或者应用加载。 It is safe to assume you can then require any file in your lib folder.

 

五、preRelease gem

当一个大的gem更新前,许多gem开发者会放出testing或者edge版本。RubyGems 支持prerelease的观点,prerelease可以使betas, alphas或者其他。

他的优点很明显。在你的gem版本中只需要多一个或者几个字母。例如,下面是一个prerelease gemspec的字段:

Gem::Specification.new do |s|
  s.name = "hola"
  s.version = "1.0.0.pre"

 

其他prerelease版本可能包含 2.0.0.rc1, 或者 1.5.0.beta.3. 只需要包含几个字母,你就做大了。这样的gem可以使用--pre,就想这样:

% gem list factory_girl -r --pre

*** REMOTE GEMS ***

factory_girl (2.0.0.beta2, 2.0.0.beta1)
factory_girl_rails (1.1.beta1)

% gem install factory_girl --pre
Successfully installed factory_girl-2.0.0.beta2
1 gem installed

 

六.扩展阅读

Several sources were used for content for this guide:

 

 

分享到:
评论

相关推荐

    gemstash, 一个 RubyGems.org 缓存和 private gem 服务器.zip

    gemstash, 一个 RubyGems.org 缓存和 private gem 服务器 什么是 Gemstash?Gemstash是远程服务器( 如 https://rubygems.org ) 和 private gem 源的缓存。在你的控制范围内,如果你使用的是多个可以访问服务器的...

    rubygems-update-3.1.3.gem

    A package (also known as a library) contains a set of functionality that can be invoked by a Ruby program, such as reading and parsing an XML ... See our guide on publishing a Gem at guides.rubygems.org

    Ruby Toolbox data on Rubygems.org-crx插件

    在Rubygems.org上查看Ruby Toolbox数据 此Chrome扩展程序从Ruby工具箱(https://www.ruby-toolbox.com/)中提取信息,以显示在rubygems.org上。 例如,如果您正在https://rubygems.org/gems/simplecov上查看诸如...

    meg:帮助管理和支持 RubyGems.org 的快速命令

    帮助管理和支持 RubyGems.org 的快速命令。 目前帮助通过 SSH 连接到 RubyGems.org 基础设施和运行命令。 安装 $ cd $ git clone git://github.com/rubygems/meg.git .meg 对于 bash 用户: $ echo 'eval "$($...

    adoption.rubygems.org

    option.rubygems.org 项目导师的姓名: Nick Quaranto,Benjamin Fleischer 项目团队的名称:丽娜·托雷斯(Lina Torres)的安吉拉(Angela Guette) 项目名称: RubyGems.org采用中心 网址: : 关于该项目: ...

    rubygems.org-backup:这是历史重写之前 ruby​​gems.org 的 BACKUP 存储库。 不使用。 请不要拉请求

    RubyGems.org(姓氏 Gemcutter) Ruby 社区的 Gem 托管。目的提供更好的 API 来处理 gems 创建更透明和可访问的项目页面使社区能够改进和增强站点链接 :#rubygems 在 Freenode 上: : :贡献请遵循我们的。 要进行...

    rubygems.org:Ruby社区的gem托管服务

    RubyGems.org(néeGemcutter) Ruby社区的gem主机。 目的 提供更好的API处理宝石 创建更透明,更易于访问的项目页面 使社区能够改善和增强网站 支持 由管理, 是一个社区资助的组织,通过门票和赞助为和的会议...

    2.4-3.0.rubygems.rar

    gem包管理

    rubygems-incident-verifiers

    ##概括此处提供的工具使您能够将 gem 的本地副本与 Rubygems.org 上的副本进行检查。 这些工具旨在让 gem 开发人员根据 Rubygems.org 服务器检查他们的本地开发副本(为什么?请参阅文档末尾的注释)。 目前正在...

    曲柄的Rubygems「Crank for Rubygems」-crx插件

    ★导航至ruby gem的GitHub或Rubygems.org页面。 在GitHub上打开'Gemfile'或'.gemspec'文件,然后单击任何gem名称。 您将被重定向到gem项目页面。 ★从上下文菜单中打开RubyGems.org中的ruby gem页面。 用鼠标突出...

    rubygems-1.8.7.gz for linux

    rubygems-1.8.7.gz rubygems-1.8.7.gz

    rubygems-master-(1).zip_GEM

    Download from: rubygems.org/pages/download Unpack into a directory and cd there Install with: ruby setup.rb # you may need admin/root privilege For more details and other options, see: ruby setup....

    RubyGems.txt

    RubyGems

    gemstash:RubyGems.org缓存和私有gem服务器

    今天或什至更好的做出贡献,并确保Bundler,RubyGems,Gemstash和其他共享工具在未来数年内都存在。 快速入门指南 设置 Gemstash旨在快速,轻松地进行设置。 到本《快速入门指南》结束时,您将能够将公共资源中的...

    guides:努力为RubyGems生态系统提供出色的文档

    从rubygems.org/pages/docs移植内容 从help.rubygems.org知识库移植内容 在这里找到许多StackOverflow / ruby​​-talk问题并获得其常见答案 填写更多指南! 设置 确保已gem install jekyll ( gem install jekyll ...

    Crank for Rubygems-crx插件

    ★导航到ruby gem的github或rubygems.org页面。 在github上打开'gemfile'或'.gemspec'文件,然后单击任何宝石名称。 您将被重定向到GEM项目页面。 ★从上下文菜单中打开RubyGems.org中的Ruby Gem页面。 在使用鼠标的...

    github-activity-web:面向前台的网站,即将提供服务

    github活动网络面向前台的网站,即将提供服务在本地运行检查是否安装了Ruby 2.1.0或更高版本: $ ruby --versionruby 2.X.X 安装捆绑器: $ gem install bundler# ... $ bundle installFetching gem metadata from ...

    ivarprudnikov.com:博客。 Jekyll采用了Bootstrap 4博客主题

    Fetching gem metadata from https://rubygems.org/............ Fetching version metadata from https://rubygems.org/... Fetching dependency metadata from https://rubygems.org/.. Resol

Global site tag (gtag.js) - Google Analytics