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 yourlib
directory, and put all your other files inlib/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
withinlib
.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 thepgarrayparser
(all lowercase). - If you want to instantiate a
PgArrayParserEngine
class, then youBasicLibraryService
must be calledPgArrayParserEngineService
. - 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
Grit's Clone Method Is Undefined
How to Capture a Part of a Screen Using Ruby on Windows
Ruby on Rails - $ Rails Server Fails Because Uglifier Gem Could Not Be Found
Project Euler #3 in Ruby Solution Times Out
Rails: Pundit::Authorizationnotperformederror
Could Not Find Gem 'Logstash-Devutils (>= 0) Ruby' in Any of the Gem Sources
Instance_Eval's Block Argument(S)- Documented? Purpose
Match Regex with Numeric Value and Decimal
How to Set Correct Ruby Version in Gem Environment
Importing CSV Data into Rails App, Using Something Other Then the Association "Id"
Search for "Enabled" Users in Net-Ldap for Ruby
Nokogiri Issues with Ruby on Rails
Can't Setup Ruby Environment - Installing Fii Gem Error
How to Set a Proxy in Rubys Net/Http
Using Fork in Windows with Ruby