Skip to content
Newer
Older
100644 195 lines (146 sloc) 6.77 KB
cd905b8 @qrush add pages for the rest
qrush authored Apr 30, 2011
1 ---
2 layout: default
3 title: Patterns
4 previous: /make-your-own-gem
5 next: /command-reference
6 ---
7
8 Patterns
9 ========
10
11 Common practices to make your gem users and other developers' lives easier.
ab5b273 @qrush stop some errors, make h3's not look stupid, start on patterns
qrush authored Apr 30, 2011
12
13 * [Consistent naming](#consistent-naming)
14 * [Semantic versioning](#semantic-versioning)
15 * [Declaring dependencies](#declaring-dependencies)
16 * [Loading code](#loading-code)
17 * [Other files](#other-files)
18 * [Requiring 'rubygems'](#requiring-rubygems)
19 * [Prerelease gems](#prerelease-gems)
20
21 <a id="consistent-naming"> </a>
22 Consistent naming
23 -----------------
24
25 > There are only two hard things in Computer Science: cache invalidation and naming things.
26 > -[Phil Karlton](http://martinfowler.com/bliki/TwoHardThings.html)
27
28 ### File names
29
30 Be consistent with how your gem files in `lib` and `bin` are named. The
31 [hola](http://github.com/qrush/hola) gem from the [make your own
32 gem](/make-your-own-gem) guide is a great example:
33
34 % tree
35 .
36 ├── Rakefile
37 ├── bin
38 │   └── hola
39 ├── hola.gemspec
40 ├── lib
41 │   ├── hola
42 │   │   └── translator.rb
43 │   └── hola.rb
44 └── test
45 └── test_hola.rb
46
47 The executable and the primary file in `lib` are named the same. A developer
48 can easily jump in and call `require 'hola'` with no problems.
49
50 ### Naming your gem
51
52 Naming your gem is important. Before you pick a name for your gem, please do a
53 quick search on [RubyGems.org](http://rubygems.org) or
54 [GitHub](http://github.com/search) to see if someone else has taken it. Once
55 you have a name, we have a [few
56 guidelines](http://blog.segment7.net/2010/11/15/how-to-name-gems) on how
57 to name them, paraphrased below.
58
59 ### Use underscores for spaces
60
61 Such as [newrelic_rpm](http://rubygems.org/gems/newrelic_rpm) or
62 [factory_girl](http://rubygems.org/gems/factory_girl). This matches the file in
63 your gem that your users will `require` along with the name. For example,
64 `gem install my_gem` will match `require 'my_gem'`
65
66 ### Use dashes for extensions
67
68 Adding new functionality to an existing gem? Use a dash. Some examples include
69 [net-http-persistent](https://rubygems.org/gems/net-http-persistent) and
70 [autotest-growl](https://rubygems.org/gems/net-http-persistent).
71
72 Usually this implies that you'll have to `require` into their directory tree
73 as well. For example, `gem install net-http-persistent` becomes `require
74 'net/http/persistent'`.
75
76 ### Don't use UPPERCASE
77
78 These gems cause problems for gem users on OSX and Windows, which use
79 case-insensitive filesystems. Plus, when installing gems it's confusing. Do I
80 run `gem install Hola` or `gem install hola` ? Just keep it lowercase.
81
82 <a id="semantic-versioning"> </a>
83 Semantic versioning
84 -------------------
85
29e00c2 @qrush versioning
qrush authored Apr 30, 2011
86 A versioning policy is merely a set of simple rules governing how version
87 numbers are allocated. It can be very simple (e.g. the version number is a
88 single number starting with 1 and incremented for each successive version), or
89 it can be really strange (Knuth’s[#knuth] TeX project had version numbers: 3,
90 3.1, 3.14, 3.141, 3.1415; each successive version added another digit to PI).
91
92 The RubyGems team **strongly recommends** gem developers to follow [Semantic
93 Versioning](http://semver.org) for their gem's versions. The RubyGems library itself does
94 not enforce a strict versioning policy, but using an "irrational" policy will
95 only be a disservice to those in the community who use your gems.
96
97 Let's say we have a 'stack' gem that holds a `Stack` class with both `push` and
98 `pop` functionalty. Our `CHANGELOG` with SemVer version bumping might look
99 like this:
100
101 * **Version 0.0.1**: The initial Stack class is release.
102 * **Version 0.0.2**: Switched to a linked list implementation because it is cooler.
103 * **Version 0.1.0**: Added a `depth` method.
104 * **Version 1.0.0**: Added `top` and made `pop` return nil (pop used to return the old top item).
105 * **Version 1.1.0**: `push` now returns the value pushed (it used it return nil).
106 * **Version 1.1.1**: Fixed a bug in the linked list implementation.
107 * **Version 1.1.2**: Fixed a bug introduced in the last fix.
108
109 This system can basically boil down to:
110
111 * **PATCH** `0.0.x` level changes for implementation level detail changes, such as
112 small bug fixes
113 * **MINOR** `0.x.0` level changes for any backwards compatible API changes, such as
114 new functionality/features
115 * **MAJOR** `x.0.0` level changes for backwards *incompatible* API changes, such
116 as changes that will break existing users code if they update
117
118 If you're dealing with a lot of gem dependencies in your application, we
119 recommend that you take a look into [Bundler](http://gembundler.com) or
120 [Isolate](http://github.com/jbarnette/isolate) which do a great job of
121 managing a complex version manifest for many gems.
122
ab5b273 @qrush stop some errors, make h3's not look stupid, start on patterns
qrush authored Apr 30, 2011
123 <a id="declaring-dependencies"> </a>
124 Declaring dependencies
125 ----------------------
126
17af0c9 @qrush dependencies
qrush authored Apr 30, 2011
127 Gems work with other gems. Here's some tips to make sure they're nice to each
128 other.
129
130 ### Runtime vs. development
131
132 RubyGems provides two main "types" of dependencies: runtime and development.
133 Runtime dependencies are what your gem needs to work (such as
134 [rails](http://rubygems.org/gems/rails) needing
135 [activesupport](http://rubygems.org/gems/activesupport)).
136
137 Development dependencies are useful for when someone wants to make
138 modifications to your gem. Once specified, someone can run
139 `gem install --dev your_gem` and RubyGems will grab both sets of dependencies
140 necessary. Usually development dependencies include test frameworks, build
141 systems, etc.
142
143 Setting them in your gemspec is easy, just use `add_runtime_dependency` and
144 `add_development_dependency`:
145
146 Gem::Specification.new do |s|
147 s.name = "hola"
148 s.version = "2.0.0"
149 s.add_runtime_dependency("daemons", ["= 1.1.0"])
150 s.add_development_dependency("bourne", [">= 0"])
151
152
153 ### Don't use `gem` from within your gem
154
155 You may have seen some code like this around to make sure you're using a
156 specific version of a gem:
157
158 gem "extlib", ">= 1.0.8"
159 require "extlib"
160
161 It's reasonable for appliations that consume gems to use this (but they could
162 also use a tool like [Bundler](http://gembundler.com)). Gems themselves **should
163 not** do this, they should instead use dependencies in the gemspec so RubyGems
164 can handle loading the dependency instead of the user.
165
166 ### The twiddle-wakka
167
168 Explain ~>.
169
ab5b273 @qrush stop some errors, make h3's not look stupid, start on patterns
qrush authored Apr 30, 2011
170 <a id="loading-code"> </a>
171 Loading code
172 ------------
173
174 <a id="other-files"> </a>
175 Other files
176 -----------
177
178 <a id="requiring-rubygems"> </a>
179 Requiring `'rubygems'`
180 --------------------
181
182 <a id="prerelease-gems"> </a>
183 Prerelease gems
184 --------------------
185
17af0c9 @qrush dependencies
qrush authored Apr 30, 2011
186
187 Credits
188 -------
189
190 Several sources were used for content for this guide:
191
192 * [Rubygems Good Practice](http://yehudakatz.com/2009/07/24/rubygems-good-practice/)
193 * [Gem Packaging: Best Practices](http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices)
194 * [How to Name Gems](http://blog.segment7.net/2010/11/15/how-to-name-gems)
Something went wrong with that request. Please try again.