discovering
GEMS
presented by Anna Mendoza at Pivotal Labs on 10.022.2013
L.A. Railsbridge Eastside/Westside Monthly Ruby Bash
What is a Gem?
The Structure of a Gem
Popular Gems
Kinds of Gems
Looking for that Gem
Let's Make a Gem
Resources
What is a Gem?
At it's most basic form,
a Ruby 'gem' is a package:
It has all the necessary files and information
for being installed on a system.
What is a Gem?
'Gemsets' are self-contained bundles of
gems that are created for specific projects,
and are loaded according to RVM.
What is a Gem?
Quoting RubyGems:
A gem is a packaged Ruby application
library. It has a name (e.g. rake)
and a version (e.g. 0.4.16)
let's see them in action, type the following:
rails new dummy-app
rails new dummy-app
Tonite we’re going to use Bundler and Rubygems.org to build a Gem.
What is a Gem?
Bundler maintains a consistent
environment for ruby applications.
It tracks the code and the ruby gems it needs to run,
so that an application will
load and
use the exact gems and versions that it needs to run.
Bundler will connect with rubygems.org,
( and any other sources that you’ve declared in your Gemfile )
and find a list of all the required gems that
meet the requirements you’ve spec’d.
What is a Gem?
RubyGems is the Ruby community’s
gem hosting service.
It’s a
package manager
for the Ruby programming language
that provides a standard format for distributing
Ruby programs and libraries.
and
It's a
tool
designed to easily manage the installation
of gems and a server for distributing them.
What is a Gem?
With RVM you can create a gemset(s).
With
bundler
you install & update the
gems or gemset.
rubygems.org distributes them to you.
What is a Gem?
Gems are fabulously powerful
and can be used to extend or
modify functionality in Ruby apps.
They’re also used to help automate tasks, speed up
your work -- all from the convenience of the command line.
What is a Gem?
For more info on how to include
a gem in your gemfile, go here.
FYI: Unless you specify a version number to
the gem command, Bundler will automatically
install the latest version of the gem.
The structure of a Gem
Every gem is different,
but most follow a basic structure.
Each gem has a name, version and platform;
which are required attributes while other
attributes are optional.
Let's explore the structure....
The structure of a Gem
Here's a classic structure:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb |-- | spec/ |-- README |-- Rakefile |-- your_gem.gemspec
Check out the RubyGems Manual;
which explains each attribute in detail.
The structure of a Gem:
The Name of a Gem
your_gem/
- Name: The gem’s name - required.
- Version: The version of the gem you are using. - required.
-
Platform: The target platform for the gem, also required.
- All of this will be defined in your gemspec.
The structure of a Gem:
The Bin folder:
your_gem/
|-- bin/
-
The bin directory: Holds any binaries that we want
to distribute with our gem. Usually an 'executable' file;
which loads the user’s PATH when the gem is installed.
- An 'Executable' is an operating system command,
like the 'bundler' command in the shell.
The structure of a Gem:
The Bin folder
-
Calling them ‘binaries’ is not quite right, since most
of the time, they are just Ruby scripts, starting off
with a ‘shebang line' --which initiates the executable:
#!/usr/bin/env ruby begin require 'your_gem' rescue LoadError require 'rubygems' require 'your_gem' end #more code goes here
The structure of a Gem:
What are 'binaries'?
-
'Binaries' are executable files from machine
code that have been compiled. That's the kind of
thing that happens with programs like C or C+.
-
Ruby is a different animal. We never compile the
code in Ruby --it's dynamic. So the bin folder holds
executable ruby scripts; that will be loaded by the
Ruby interpreter.
The structure of a Gem:
The lib folder:
your_gem/
|-- bin/ |-- lib/| | |-- your_gem.rb | |-- your_gem/
-
The lib directory: All the code for the gem
is under the lib/ directory. -
This directory gets added to your
$LOAD_PATH and
contains two things:• A ruby file with the name of the gem ( your_gem.rb )• A directory of the gem’s name ( your_gem/ ).
The structure of a Gem:
The lib folder:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb
-
If there were more files in lib/your_gem,
they’d be required here, too.
-
Why?
So that you can break up the project
into as many files as you want, name them
whatever you want and nobody gets hurt.
THINK:
If you have two gems installed, and both of them have their lib directories
included, and they both are named ‘json.rb’, which one
is going to get loaded?
It causes name-collision problems.
The pattern to solve this in a ‘version.rb’ file would be this:
module your_gem VERSION = "0.0.1" end
The CONSTANT would be used in your gemspec
to define the version number of your gem.
So with a version number noted, it allows
for multiple version to be installed.
The structure of a Gem
The spec or test file:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb |-- | spec/
-
The test or spec directory:
When you’re working with with RSpec,
this folder is called ‘spec’, otherwise it’s called
‘test’ file. It holds all the tests for your gem.
The structure of a Gem
The README file:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb |-- | spec/ |-- README
-
The README file: This is where the documentation
is loaded. When you install a gem, documentation is
automatically generated. If you go to any gem file,
on github, you’ll start to note the logic of the README file. - REAMD.md These files are written in markdown.
The structure of a Gem
The Rakefile:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb |-- | spec/ |-- README |-- Rakefile
The structure of a Gem
To download and install ‘rake’
gem install rake
-
Rakefile is extremely useful.
It can hold various tasks to help build,
test and debugg your gem.
The structure of a Gem
The gemspec:
your_gem/
|-- bin/ |-- lib/ | |-- your_gem.rb | |-- your_gem/ | | |-- source1.rb | | |-- source2.rb |-- | spec/ |-- README |-- Rakefile |-- your_gem.gemspec
-
The gemspec: As the name implies
—contains all the gem’s specification by defining
several attributes. It’s got the gem’s files, name,
version, summary, author info and email, and homepage.
The structure of a Gem
The Specification class contains the info for a Gem:
Gem::Specification.new do |s|
s.name = ‘your_gem’ s.version = ‘0.1.0’ s.platform = Gem::Platform::RUBY s.summary = "Sample gem" s.description = "The big takeaway about the gem!" s.authors = ["Girl Coder"] s.email = ["girl_coder@gmail.com"] s.homepage = "http://github.com/girl_coder/your_gem" s.required_rubygems_version = ">= 1.9.3" # If you have runtime dependencies, add them here s.add_runtime_dependency ‘launchy’, ‘~> 1.2" # If you have development dependencies, add them here s.add_development_dependency "rspec", "-> 2.5.0" # The list of files to be contained in the gem s.files = `git ls-files`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } # s.extensions = `git ls-files ext/extconf.rb`.split("\n") s.require_path = 'lib' end
I like using Justin French’s
formtastic gem.
It’s got the basic format and it’s a great gem;
when you need to build forms. Let's install it:
gem install formtastic
- You can clone it:
git clone https://github.com/justinfrench/formtastic.git
- Or simply download the Zip file from Github:
https://github.com/justinfrench/formtastic
Let's look at the structure
of the
formtastic
gem.
formastic/ |-- app/ | |-- assets |-- Appraisals |-- CHANGELOG |-- formtastic.gemspec |-- Gemfile |-- gemfiles/ |-- lib/ | |-- formtastic | |-- formtastic.rb | |-- generators | |-- locale |-- MIT-LICENSE |-- Rakefile |-- README.textfile |-- RELEASE_PROCESS |-- sample/ |-- spec/
There are 3 kinds of gems...
-
Vendor Gems - Wrappers for JQuery Libraries
and CSS Libraries. So that they are easily deployed
from your Asset Pipeline.
EX: jquery-rails
-
‘Plugin’ Gems -
Do not have any front-end plugin
functionality. No views, but quite common.
Ex: acts-as-taggable-on
-
Engine Gems -
Less common, has views
Ex: ‘devise’ ( simpler )
Ex: ‘spree’ ( multiple gems )
Ex: ‘radiant’ ( multiple gems )
THE KINDS OF GEMS...
So Gems are very useful for not reinventing the
wheel and avoiding duplication.
That’s basically it.
Many Ruby developers create and publish awesome gems;
which address specific requirements, solve specific problems
or add specific functionality.
Anyone who comes across similar requirements or
problems can use them and eventually improve them.
That’s the joint awesomeness of Ruby’s strong
open-source foundation and extreme flexibility.
Looking for that Gem
What is it that I’m looking for?
-
Look at the activity in their community
-- are projects actively updated?
Are there easily accessible mailing lists / a wiki/ IRC?
How active are they? What's the general tone?
-
Look at their code. Are there test suites?
Are they test suites that help me understand
the library? Is the code clean? Documented?
Commented usefully? Does it look like a ridiculous
mess, or like it's had thought put into it at every point?
Looking for that Gem
What is it that I’m looking for?
-
Use their code in a simplified, but similar,
manner to how you actually need to use it.
Did I run into any major stumbling blocks?
-
Screw flipping a coin and sticking with it.
Sooner or later, whatever lib you're using isn't
going to serve your needs, and you'll want
to modify it's behavior.
web resources:
railscasts:
OKAY!
LET’S MAKE A GEM!
gems-deck
By Anna Mendoza
gems-deck
- 1,721