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:

a self contained format of Ruby code
that can be easily distributed

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
 



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 Rakefile: Most gems have a Rakefile,
    which the rake program uses to automate tests,
     generate code, and perform other tasks.
    rake is just Ruby’s ‘make’ program.

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:

  1. rvm
  2. bundler
  3. rubygems
  4. the ruby toolbox



                       railscasts:




OKAY!




LET’S MAKE A GEM!

gems-deck

By Anna Mendoza

gems-deck

  • 1,654