Gotchas for Writing Rubygems

Gotchas for writing rubygems

Gem Packaging: Best Practices gives a lot of advice, some of which include

  • Don't pollute the global load path. Ideally, only have foo.rb in your lib directory, and put all your other files in lib/foo.

  • Don't require files using __FILE__.

  • Don't rely on anything outside the load path. Folders may not have the same structure as in your original version. For example, don't use something like

    VERSION = ::File.read(::File.join(::File.dirname(FILE), "..", "..", "VERSION")).strip

  • Don't manage $LOAD_PATH within lib.

  • Provide a VERSION constant.

  • Don't depend on rubygems. The person using your code may not be using rubygems, but some other packaging system (or no packaging system). Similarly, don't mention version dependencies in the code itself, or rescue Gem::LoadError.

Rubygems dependencies. Please... argues that you shouldn't list optional runtime dependencies, and should separate developer from runtime dependencies.

From my own experience: if nothing else, try building and installing your gem locally before releasing it into the wild. It avoids brown paper bag releases.

Ruby : How to write a gem?

Rubygems.org's Guides is one of the best resources for writing your own gem.

If you're using Bundler in your app, you might want to look at Ryan Bigg's guide to Developing a RubyGem using Bundler and the Railscast on creating gems with Bundler.

If you're interested in tools to help you write gems:

  • Jeweler - Opinionated tool for creating and managing Rubygem projects. There's also a Gemcutter and Jeweler Railscast.
  • Hoe - From the guys at seattlrb.
  • gem-this adds a bunch of helpful rake tasks.

Some tutorials/guides:

  • Creating Your First Gem
  • Using bundler and rvm to build a rubygem - Using bundler and rvm to create a gem
  • Gem Packaging: Best Practices
  • Ruby Gem Recipe - Intro guide to creating a gem using bundler and jeweler
  • How to build a ruby gem and host it on gemcutter - tutorial using echoe and gemcutter
  • The Truth About Gemspecs - goes over gemspecs and tips for dealing with them
  • Packaging with RubyGems - a quickstart guide for Jeweler
  • gem that - James Adam - reviews tools that help build gems (hoe, newgem, echoe, gemhub, jeweler, gem this)
  • Using Gemcutter's Api from the Commandline
  • New Gem with Bundler – Sample Rakefile - Useful rakefile for deploying and publishing a gem
  • Let's Write a Gem
  • How To Build A Ruby Gem With Bundler, Test-Driven Development, Travis CI And Coveralls, Oh My!

What are the steps needed to create and publish a rubygem of your own?

There are several tools to help you build your own gems. hoe and newgem are the best-known, and have a lot of good qualities. However, hoe adds itself as a dependency to your gem, and newgem has become a very large tool, one that I find unwieldy when I want to create and deploy a gem quickly.

My favorite tool is Mr Bones by Tim Pease. It’s lightweight, featureful, and does not add dependencies to your project. To create a project with it, you just run bones <my_project_name> on the command line, and a skeleton is built for you, complete with a lib directory for your code, a bin directory for your tools, and a test directory. The configuration is in a Rakefile, and it’s clear and concise. Here's the configuration for a project I did a few months ago:

load 'tasks/setup.rb'

ensure_in_path 'lib'
require 'friend-feed'

task :default => 'test'

PROJ.name = 'friend-feed'
PROJ.authors = 'Clinton R. Nixon'
PROJ.email = 'crnixon@gmail.com'
PROJ.url = 'friend-feed.rubyforge.org'
PROJ.rubyforge_name = 'friend-feed'
PROJ.dependencies = ['json']
PROJ.version = FriendFeed::VERSION
PROJ.exclude = %w(.git pkg)

Mr Bones has the standard set of features you’d expect: you can use it to package up gems and tarfiles of your library, as well as release it on RubyForge and deploy your documentation there. Its killer feature, though, is its ability to freeze its skeleton in your home directory. When you run bones --freeze, a directory named .mrbones is copied into your home directory. You can edit the files in there to make a skeleton for your gems that works the way you work, and from then on, when you run bones to create a new gem, it will use your personal gem skeleton. You can unfreeze Mr Bones by running bones --unfreeze and your skeleton will be backed up, and the default skeleton will be used again.

(Editorial note: I wrote a blog post about this several months ago, and most of this is copied from it.)

In depth Ruby Gem development resources (book, video, sites)

Rubygems aren't related to distributed programming.

Can you please provide more details about what you're after, if you aren't asking a duplicate question? Related questions within Stack Overflow include:

  • Gotchas for writing rubygems
  • Ruby : How to write a gem ?
  • What are the steps needed to create and publish a rubygem of your own?
  • What is the modern way to structure a ruby gem?

(I know this is more of a comment than an answer, but it's too big to fit in the comments section)

Suggestions for Ruby Gem authoring (ie. setup, environment etc)

Whether you make it a stand-alone or pull it apart after the fact probably depends on how well you see the boundary between your gem and the rest of the code. If the responsibilities are very clear I'd start out apart. If its not clear exactly where things start/end you probably want to make it work before you make it right to stop yourself from doing a bunch of busy-work multiple times.

However you manage to pull the reusable portions of your code out, once you have the code ready to go (or before if that's the way you roll) you may want to take a look at jeweler, http://github.com/technicalpickles/jeweler, particularly if you're going to share the gem with the community.

There's also a book: Practical Ruby Gems, it's a bit dated, but you can find a used copy for less than $1.

Easier way to test gem

Git clone it in an arbitrary folder, add its lib path to $: in the rakefile if needed (you actually don't in this case, as RakeTest should add it for you), and run rake test directly.

From irb, proceed similarly: add the lib path to $: to bypass the packaged gem. But note that you'll need to reload it when you change it, so it's less convenient than rake.

For completeness, in case you or a future visitor is unfamiliar with Rake:

Running Ruby unit tests with Rake

What are the pitfalls and solutions when setting up Rails/Mysql on Leopard?

The ruby mysql gem doesn't like the 64-bit version on Leopard. If you can, downgrade.

Then you should call the sudo gem install mysql with the options (change it to your path):

--with-mysql-dir=/usr/local/mysql 
--with-mysql-lib=/usr/local/mysql/lib
--with-mysql-include=/usr/local/mysql/include

Worked for me. (The blog post which help me is in German, might help you anyway.)

http://www.code-schubser.de/2008/12/05/mysql-gem-unter-macosx-leopard-installieren/

Issues loading java class into gem in JRuby

Having recently worked on a JRuby extension myself, here are some of the gotchas which I have found through experiment -- and which seem to cause you problems too:

  • The java package must match the Ruby module in which your class sits. If your class is in the PgArrayParser module, your class must be in the pgarrayparser (all lowercase).
  • If you want to instantiate a PgArrayParserEngine class, then you BasicLibraryService must be called PgArrayParserEngineService.
  • When using @JRubyMethod, specify the name of the method.

I have found Yoko's article on the subject most useful, along with this recent post.

I have applied these different elements to your project here, and I can call the method from IRB -- and the first spec passes!

Rails optional gem config

I answered a similar question of my own here

User-level bundler Gemfile

One way to do this is to create different environments:

group :scott do 
end

Then

bundle --with-env=scott


Related Topics



Leave a reply



Submit