How to Make a Ruby Gem	
Clare Glinka

1
Who is this talk for?	
•Me, a few months ago
•Someone who is:
•new to Rails
•new to Ruby
•new to programming
2
What is a gem?
• Container that hold widely-reusable code.
• Code that is useable in many different contexts.

3
Tools to help with making gems:
•Bundler
•Jeweler
•gemcutter
•others!

4
Building a Gem
<that generates cheesey adventure plots>
with Bundler

5
Step 0.5: $ gem install bundler

6
Step 1: $ bundle gem adventure

7
=> create adventure/Gemfile
create adventure/Rakefile
create adventure/LICENSE.txt
create adventure/README.md
create adventu...
Gem structure
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├...
Step 3: Finish .gemspec

10
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
adventure.gemspec
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
requi...
Required specs
•name
•version
•summary
•require_paths
•files
•rubygems_version

13
spec.name

14
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
spec.version

16
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
lib/adventure/version.rb

module Adventure
VERSION = "0.0.1"
end

19
Versioning
• Use semantic versioning.
•0.0.X
- bugfixs
•0.X.0
- additional functionality that is backward compatible.
•X.0....
Version constraints
• ~> 1.2
- all versions before 2 . 0
• ~> 1 . 3 . 5
- all versions before 1. 4 . 0

21
spec.summary

22
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
spec.require_paths

25
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
Protect the load path!
$ pry
[1] pry(main)> $LOAD_PATH
=> ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1....
Protect the load path!
[2] pry(main)> require 'adventure'
=> true
[3] pry(main)> $LOAD_PATH
=> ["/rbenv/versions/2.0.0-p35...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
spec.files

30
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
$ git ls-files
.gitignore
Gemfile
LICENSE.txt
README.md
Rakefile
adventure.gemspec
lib/adventure.rb
lib/adventure/version....
$	
  pry
[1]	
  pry(main)>	
  `git	
  ls-­‐files`
=>	
  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile
nadventure.gems...
$	
  pry
[1]	
  pry(main)>	
  `git	
  ls-­‐files`
=>	
  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile
nadventure.gems...
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
$	
  pry
[1]	
  pry(main)>	
  Dir.glob('**/**')
=>	
  ["adventure.gemspec",
	
  "Gemfile",
	
  "lib",
	
  "lib/adventure",...
spec.rubygems_version

39
Other Specs:
•authors
•email
•homepage
•license
•executables
•test_files
•add_development_dependency
•add_dependency

40
spec.authors
spec.email
spec.homepage

41
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
spec.license

44
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
spec.executables
spec.test_files

47
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
Step 4: Write some code!

49
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
require	
  "adventure/version"
module	
  Adventure
	
  	
  #	
  Your	
  code	
  goes	
  here...
end

51
Desired output:

“There is a disgruntled shopkeeper with a secret past and a
grad student with a knack for cooking.
They fi...
require	
  "adventure/version"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
  def	
  make_plot
	
  	
  	
  	
  ...
Step 5: build and install the gem

54
$ gem build adventure.gemspec
WARNING: no description specified
Successfully built RubyGem
Name: adventure
Version: 0.0.1
F...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
├── adventure-0.0.1.gem...
$ gem install adventure-0.0.1.gem
Successfully installed adventure-0.0.1
1 gem installed

57
$	
  pry
[1]	
  pry(main)>	
  require	
  'adventure'
=>	
  true
[2]	
  pry(main)>	
  plot	
  =	
  Adventure::Plot.new
=>	
...
The easier way... Rake tasks!

59
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.r...
Gemfile

source	
  'https://rubygems.org'
#	
  Specify	
  your	
  gem's	
  dependencies	
  in	
  adventure.gemspec
gemspec
...
Rakefile

require	
  "bundler/gem_tasks"

63
$	
  rake	
  -­‐T
rake	
  build	
  	
  	
  	
  #	
  Build	
  adventure-­‐0.0.1.gem	
  into	
  the	
  pkg	
  directory.
rak...
$	
  rake	
  build
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.

65
$	
  rake	
  install
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.
adventure	
  (0.0.1)	
  installed.

6...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
├── pkg
│
└── adventure...
Step 6: Release the gem!

68
69
$	
  rake	
  release

70
And if everything has gone terribly wrong...

$ gem yank

*** Use with caution
71
No More Hardcoding!

72
adventure.json
{
	
  	
  	
  	
  "characters":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  clever	
  dragon",
	
  	
  	
  	...
spec.add_dependency

74
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
$ bundle install
Resolving dependencies...
Using bundler (1.5.2)
Using json (1.7.7)
Using rake (0.9.6)
Using adventure (0....
require	
  "adventure/version"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
  def	
  make_plot
	
  	
  	
  	
  ...
lib/adventure.rb
require	
  "adventure/version"
require	
  "json"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
...
$	
  rake	
  install
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.
adventure	
  (0.0.1)	
  installed.

7...
lib/adventure/version.rb

module Adventure
VERSION = "0.0.1"
end

80
lib/adventure/version.rb

module Adventure
VERSION = "1.0.0"
end

81
$	
  rake	
  install
adventure	
  1.0.0	
  built	
  to	
  pkg/adventure-­‐1.0.0.gem.
adventure	
  (1.0.0)	
  installed.

8...
$	
  pry
[1]	
  pry(main)>	
  require	
  'adventure'
=>	
  true
[2]	
  pry(main)>	
  plot	
  =	
  Adventure::Plot.new
=>	
...
Set Up Testing with <RSpec>

84
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require...
$ rspec --init
create spec/spec_helper.rb
create .rspec

86
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├── .gitignore
├── .rspec
├── adventure.gemspec
├── pkg
├──...
spec/spec_helper.rb
#	
  This	
  file	
  was	
  generated	
  by	
  the	
  `rspec	
  -­‐-­‐init`	
  command.	
  Conventiona...
spec/spec_helper.rb
require	
  'adventure'
#	
  This	
  file	
  was	
  generated	
  by	
  the	
  `rspec	
  -­‐-­‐init`	
  ...
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├── .gitignore
├── .rspec
├── adventure.gemspec
├── pkg
├──...
spec/adventure_spec.rb

require	
  'spec_helper'
describe	
  Adventure::Plot	
  do
	
  	
  describe	
  "#make_plot"	
  do
...
$ bundle exec rspec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
.
Finished ...
Rakefile

require	
  "bundler/gem_tasks"
require	
  "rspec/core/rake_task"
RSpec::Core::RakeTask.new('spec')

93
Rakefile

require	
  "bundler/gem_tasks"
require	
  "rspec/core/rake_task"
RSpec::Core::RakeTask.new('spec')

94
$ rake spec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
.
Finished in 0.000...
96
Resources
guides.rubygems.org

link to slides @ClareGlinka_

97
Upcoming SlideShare
Loading in …5
×

How to make a Ruby Gem - Austin on Rails, January 2014

1,703 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,703
On SlideShare
0
From Embeds
0
Number of Embeds
670
Actions
Shares
0
Downloads
6
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

How to make a Ruby Gem - Austin on Rails, January 2014

  1. 1. How to Make a Ruby Gem Clare Glinka 1
  2. 2. Who is this talk for? •Me, a few months ago •Someone who is: •new to Rails •new to Ruby •new to programming 2
  3. 3. What is a gem? • Container that hold widely-reusable code. • Code that is useable in many different contexts. 3
  4. 4. Tools to help with making gems: •Bundler •Jeweler •gemcutter •others! 4
  5. 5. Building a Gem <that generates cheesey adventure plots> with Bundler 5
  6. 6. Step 0.5: $ gem install bundler 6
  7. 7. Step 1: $ bundle gem adventure 7
  8. 8. => create adventure/Gemfile create adventure/Rakefile create adventure/LICENSE.txt create adventure/README.md create adventure/.gitignore create adventure/adventure.gemspec create adventure/lib/adventure.rb create adventure/lib/adventure/version.rb Initializing git repo in /Users/me/code/adventure 8
  9. 9. Gem structure adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 9
  10. 10. Step 3: Finish .gemspec 10
  11. 11. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 11
  12. 12. adventure.gemspec lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 12
  13. 13. Required specs •name •version •summary •require_paths •files •rubygems_version 13
  14. 14. spec.name 14
  15. 15. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 15
  16. 16. spec.version 16
  17. 17. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 17
  18. 18. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 18
  19. 19. lib/adventure/version.rb module Adventure VERSION = "0.0.1" end 19
  20. 20. Versioning • Use semantic versioning. •0.0.X - bugfixs •0.X.0 - additional functionality that is backward compatible. •X.0.0 - additional functionality that breaks backwards compatibility. 20
  21. 21. Version constraints • ~> 1.2 - all versions before 2 . 0 • ~> 1 . 3 . 5 - all versions before 1. 4 . 0 21
  22. 22. spec.summary 22
  23. 23. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 23
  24. 24. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 24
  25. 25. spec.require_paths 25
  26. 26. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 26
  27. 27. Protect the load path! $ pry [1] pry(main)> $LOAD_PATH => ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"] 27
  28. 28. Protect the load path! [2] pry(main)> require 'adventure' => true [3] pry(main)> $LOAD_PATH => ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/adventure-0.0.1/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"] 28
  29. 29. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 29
  30. 30. spec.files 30
  31. 31. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 31
  32. 32. $ git ls-files .gitignore Gemfile LICENSE.txt README.md Rakefile adventure.gemspec lib/adventure.rb lib/adventure/version.rb 32
  33. 33. $  pry [1]  pry(main)>  `git  ls-­‐files` =>  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb n" [2]  pry(main)>  `git  ls-­‐files`.split($) =>  [".gitignore",  "Gemfile",  "LICENSE.txt",  "README.md",  "Rakefile",  "adventure.gemspec",  "lib/adventure.rb",  "lib/adventure/version.rb"] 33
  34. 34. $  pry [1]  pry(main)>  `git  ls-­‐files` =>  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb n" [2]  pry(main)>  `git  ls-­‐files`.split($) =>  [".gitignore",  "Gemfile",  "LICENSE.txt",  "README.md",  "Rakefile",  "adventure.gemspec",  "lib/adventure.rb",  "lib/adventure/version.rb"] 34
  35. 35. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "adventure.gemspec", "lib/adventure.rb", "lib/ adventure/version.rb"] 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.4" spec.add_development_dependency "rake" end 35
  36. 36. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 36
  37. 37. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" Dir.glob(‘**/*’) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 37
  38. 38. $  pry [1]  pry(main)>  Dir.glob('**/**') =>  ["adventure.gemspec",  "Gemfile",  "lib",  "lib/adventure",  "lib/adventure/random.txt",  "lib/adventure/version.rb",  "lib/adventure.rb",  "LICENSE.txt",  "Rakefile",  "README.md"] 38
  39. 39. spec.rubygems_version 39
  40. 40. Other Specs: •authors •email •homepage •license •executables •test_files •add_development_dependency •add_dependency 40
  41. 41. spec.authors spec.email spec.homepage 41
  42. 42. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 42
  43. 43. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://www.github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 43
  44. 44. spec.license 44
  45. 45. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://www.github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 45
  46. 46. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 46
  47. 47. spec.executables spec.test_files 47
  48. 48. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 48
  49. 49. Step 4: Write some code! 49
  50. 50. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 50
  51. 51. require  "adventure/version" module  Adventure    #  Your  code  goes  here... end 51
  52. 52. Desired output: “There is a disgruntled shopkeeper with a secret past and a grad student with a knack for cooking. They fight crime!” 52
  53. 53. require  "adventure/version" module  Adventure    class  Plot        def  make_plot            characters  =  ["a  clever  dragon",                                          "a  ruthless  detective",                                          "a  disgruntled  shopkeeper",                                          "an  aging  cowboy",                                          "a  grad  student",                                          "a  mystical  lizard"]            with  =  ["nothing  left  to  loose",                            "a  secret  past",                              "an  enchanted  sword",                              "a  grudge",                              "a  knack  for  cooking"]            who  =  ["likes  kebabs",                            "organizes  poetry  nights",                            "is  a  world-­‐famous  cyclist",                            "lived  in  a  circus"]            "There  is  #{characters.sample}  with  #{with.sample}  and  #{characters.sample}   who  #{who.sample}.  They  fight  crime!"        end    end end 53
  54. 54. Step 5: build and install the gem 54
  55. 55. $ gem build adventure.gemspec WARNING: no description specified Successfully built RubyGem Name: adventure Version: 0.0.1 File: adventure-0.0.1.gem 55
  56. 56. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec ├── adventure-0.0.1.gem └── lib ├── adventure.rb └── adventure └── version.rb 56
  57. 57. $ gem install adventure-0.0.1.gem Successfully installed adventure-0.0.1 1 gem installed 57
  58. 58. $  pry [1]  pry(main)>  require  'adventure' =>  true [2]  pry(main)>  plot  =  Adventure::Plot.new =>  #<Adventure::Plot:0x007fe2a4106498> [3]  pry(main)>  plot.make_plot =>  "There  is  a  grad  student  with  a  knack  for  cooking  and  a  ruthless   detective  who  likes  kebabs.  They  fight  crime!" 58
  59. 59. The easier way... Rake tasks! 59
  60. 60. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 60
  61. 61. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 61
  62. 62. Gemfile source  'https://rubygems.org' #  Specify  your  gem's  dependencies  in  adventure.gemspec gemspec 62
  63. 63. Rakefile require  "bundler/gem_tasks" 63
  64. 64. $  rake  -­‐T rake  build        #  Build  adventure-­‐0.0.1.gem  into  the  pkg  directory. rake  install    #  Build  and  install  adventure-­‐0.0.1.gem  into  system   gems. rake  release    #  Create  tag  v0.0.1  and  build  and  push   adventure-­‐0.0.1.gem  to  Rubygems 64
  65. 65. $  rake  build adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. 65
  66. 66. $  rake  install adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. adventure  (0.0.1)  installed. 66
  67. 67. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec ├── pkg │ └── adventure-0.0.1.gem └── lib ├── adventure.rb └── adventure └── version.rb 67
  68. 68. Step 6: Release the gem! 68
  69. 69. 69
  70. 70. $  rake  release 70
  71. 71. And if everything has gone terribly wrong... $ gem yank *** Use with caution 71
  72. 72. No More Hardcoding! 72
  73. 73. adventure.json {        "characters":  [                "a  clever  dragon",                "a  ruthless  detective",                "a  disgruntled  shopkeeper",                "an  aging  cowboy",                "a  grad  student",                "a  mystical  lizard"        ],        "with":  [                "nothing  left  to  loose",                "a  secret  past",                "an  enchanted  sword",                "a  grudge",                "a  knack  for  cooking"        ],        "who":  [                "likes  kebabs",                "organizes  poetry  nights",                "is  a  world-­‐famous  cyclist",                "lived  in  a  circus"        ] } 73
  74. 74. spec.add_dependency 74
  75. 75. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_dependency "json" spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 75
  76. 76. $ bundle install Resolving dependencies... Using bundler (1.5.2) Using json (1.7.7) Using rake (0.9.6) Using adventure (0.0.1) from source at . Your bundle is complete! 76
  77. 77. require  "adventure/version" module  Adventure    class  Plot        def  make_plot            characters  =  ["a  clever  dragon",                                          "a  ruthless  detective",                                          "a  disgruntled  shopkeeper",                                          "an  aging  cowboy",                                          "a  grad  student",                                          "a  mystical  lizard"]            with  =  ["nothing  left  to  loose",                            "a  secret  past",                              "an  enchanted  sword",                              "a  grudge",                              "a  knack  for  cooking"]            who  =  ["likes  kebabs",                            "organizes  poetry  nights",                            "is  a  world-­‐famous  cyclist",                            "lived  in  a  circus"]            "There  is  #{characters.sample}  with  #{with.sample}  and  #{characters.sample}   who  #{who.sample}.  They  fight  crime!"        end    end end 77
  78. 78. lib/adventure.rb require  "adventure/version" require  "json" module  Adventure    class  Plot        def  make_plot(plotdevice)            plotholes  =  JSON.load(File.new(plotdevice))            characters  =  plotholes["characters"]            with              =  plotholes["with"]            who                =  plotholes["who"]            "There  is  #{characters.sample}  with  #{with.sample}  and   #{characters.sample}  who  #{who.sample}.  They  fight  crime!"        end    end end 78
  79. 79. $  rake  install adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. adventure  (0.0.1)  installed. 79
  80. 80. lib/adventure/version.rb module Adventure VERSION = "0.0.1" end 80
  81. 81. lib/adventure/version.rb module Adventure VERSION = "1.0.0" end 81
  82. 82. $  rake  install adventure  1.0.0  built  to  pkg/adventure-­‐1.0.0.gem. adventure  (1.0.0)  installed. 82
  83. 83. $  pry [1]  pry(main)>  require  'adventure' =>  true [2]  pry(main)>  plot  =  Adventure::Plot.new =>  #<Adventure::Plot:0x007fc079139e80> [3]  pry(main)>  plot.make_plot('adventure.json') =>  "There  is  a  clever  dragon  with  a  secret  past  and  a  clever   dragon  who  is  a  world-­‐famous  cyclist.  They  fight  crime!" 83
  84. 84. Set Up Testing with <RSpec> 84
  85. 85. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_dependency "json" spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependencyependency "rake" spec.add_development_dependencyependency "rspec" end 85
  86. 86. $ rspec --init create spec/spec_helper.rb create .rspec 86
  87. 87. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── .gitignore ├── .rspec ├── adventure.gemspec ├── pkg ├── lib └── spec └── spec_helper.rb 87
  88. 88. spec/spec_helper.rb #  This  file  was  generated  by  the  `rspec  -­‐-­‐init`  command.  Conventionally,  all #  specs  live  under  a  `spec`  directory,  which  RSpec  adds  to  the  `$LOAD_PATH`. #  Require  this  file  using  `require  "spec_helper"`  to  ensure  that  it  is  only #  loaded  once. # #  See  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration RSpec.configure  do  |config|    config.treat_symbols_as_metadata_keys_with_true_values  =  true    config.run_all_when_everything_filtered  =  true    config.filter_run  :focus    #  Run  specs  in  random  order  to  surface  order  dependencies.  If  you  find  an    #  order  dependency  and  want  to  debug  it,  you  can  fix  the  order  by  providing    #  the  seed,  which  is  printed  after  each  run.    #          -­‐-­‐seed  1234    config.order  =  'random' end 88
  89. 89. spec/spec_helper.rb require  'adventure' #  This  file  was  generated  by  the  `rspec  -­‐-­‐init`  command.  Conventionally,  all #  specs  live  under  a  `spec`  directory,  which  RSpec  adds  to  the  `$LOAD_PATH`. #  Require  this  file  using  `require  "spec_helper"`  to  ensure  that  it  is  only #  loaded  once. # #  See  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration RSpec.configure  do  |config|    config.treat_symbols_as_metadata_keys_with_true_values  =  true    config.run_all_when_everything_filtered  =  true    config.filter_run  :focus    #  Run  specs  in  random  order  to  surface  order  dependencies.  If  you  find  an    #  order  dependency  and  want  to  debug  it,  you  can  fix  the  order  by  providing    #  the  seed,  which  is  printed  after  each  run.    #          -­‐-­‐seed  1234    config.order  =  'random' end 89
  90. 90. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── .gitignore ├── .rspec ├── adventure.gemspec ├── pkg ├── lib └── spec ├── spec_adventure.rb └── spec_helper.rb 90
  91. 91. spec/adventure_spec.rb require  'spec_helper' describe  Adventure::Plot  do    describe  "#make_plot"  do        it  "does  something"  do        end    end end 91
  92. 92. $ bundle exec rspec Run options: include {:focus=>true} All examples were filtered out; ignoring {:focus=>true} . Finished in 0.00052 seconds 1 example, 0 failures Randomized with seed 38431 92
  93. 93. Rakefile require  "bundler/gem_tasks" require  "rspec/core/rake_task" RSpec::Core::RakeTask.new('spec') 93
  94. 94. Rakefile require  "bundler/gem_tasks" require  "rspec/core/rake_task" RSpec::Core::RakeTask.new('spec') 94
  95. 95. $ rake spec Run options: include {:focus=>true} All examples were filtered out; ignoring {:focus=>true} . Finished in 0.00052 seconds 1 example, 0 failures Randomized with seed 38431 95
  96. 96. 96
  97. 97. Resources guides.rubygems.org link to slides @ClareGlinka_ 97

×