Helpful Configure Options For Development

Recently I decided to install Ruby 1.9. I’ve been compiling programs from source more and more often and I am getting used to the normal workflow: configure, make, make install. But Ruby 1.9 was different. I wanted to easily reference both the Ruby 1.8 and Ruby 1.9 so I could easily work with both. I came across a neat switch that I had never cared to use before but made perfect sense for my situation:

shell> ./configure --program-suffix=WHATEVER ...

That neat switch will make it so when you finally `make install` the output binaries are named rubyWHATEVER, irbWHATEVER, etc. Obviously you should choose something better then WHATEVER. I went with ‘–program-suffix=19′ so that all my Ruby 1.9 binaries are exactly the same as the 1.8 binaries but with “19″ on the end. Such as ruby19, irb19, etc. This will really save me some time as I experiment with Ruby 1.9.

Note when installing Ruby from source on Mac OS X you may run into problems, check out this article or the one linked above for the fixes.

Also, since I had now had a ruby19 I figured I’d make a ruby18 as well. I already have my own ‘~/bin’ directory in my shell’s path. So I added the following symbolic link which makes `ruby18` reference my default Ruby 1.8 interpreter:

shell> ln -s `which ruby` ruby18

The `which ruby` in my case evaluates to the default installation of Ruby. It may not be the case on your computer. That depends on how you’ve modified your path. So the explicit version that should work on any mac is:

shell> ln -s /usr/bin/ruby ruby18

Here the symbol link means I can use `ruby18` if I want to be dead sure I’m using Ruby 1.8, and likewise `ruby19` when I want to use Ruby 1.9. I know I’m not the first person to do this, but I’m happy and I want to spread the joy.

Other notable configure options are:

shell> ./configure --prefix=PREFIX ...

This makes it so when you run `make install` it will install the files to PREFIX/(here). An example would typically be ‘–prefix=/usr/local’ to install the files into the /usr/local dir. However, that is normally the default installation directory and therefore most people don’t bother changing it. I’ve used this prefix to install temporary things directly into my home directory. This made it easy to find, work with, and delete when I was done.

The Big Picture Analyzer

One of my favorite blogs that I follow is The Big Picture. Its a collection of amazing pictures. Make sure that you go into each article, that single picture is only a teaser and often collections have over 30 images.

(JOERG KOCH/AFP/Getty Images)

At the Big Picture it is very common for commenters to list the numbers of the images that they really liked. This intrigued me a little bit. Also, the comments on the main page are limited to just
100 comments, when there might actually be over 2000 comments on some collections.

So, I wrote a Ruby Script that I call bigpicvotes that takes in the URL to a Big Picture site and analyzes the comments to make a guess at what pictures were voted for the most!

bigpicvotes usage

Above is a sample usage on an article with now over 2600 comments. Notice that the URL you provide can be either the “all comments” URL or just the URL with the pictures that you are likely to be looking at. Also, the usage allows for a second optional parameter. This is to show the top N images instead of defaulting to the top 10.

One last thing. To use it you will need the Hpricot gem. That is simple enough to install:

shell> gem install hpricot

Again, the script is available here: bigpicvotes

SotD – Remove the First N Characters From a Line

I was asked today to remove the first 6 characters from every line in a document. It was known that each line contained at least 6 characters. For me, that means a find a replace. Here is how I did it (in a number of different ways). Can you think of any other ways to do it?

cut -c7-
rr ^.{6}
colrm 1 6
rr s/^.{6}//
sed 's/^.\{6\}//'
perl -pe 's/^.{6}//'
ruby -pe 'sub /^.{6}/,""'
gawk 'BEGIN{FIELDWIDTHS="6 999"}{print$2}'

I was pretty happy with rr taking the prize for least characters. I do want to point out that since rr defaults to multi-line and global replacements the “^” is required. If you wanted to remove the “^” (like you could with sed, perl, and ruby) then you would have to use the “–line” or “-l” and “–notglobal” or “-ng” options. So a single character replaces 7! If you want to grab rr just do:

$ sudo gem install regex_replace

Also, here is a link to gawk – GNU’s awk. This has the very nice FIELDWIDTHS variable, which is extremely useful!

Also keep in mind that the regular expressions above ^.{6} only work because the lines were known to have at least 6 characters. If we didn’t know that we would have had to use something like ^.{0,6} to allow up to 6 characters (and even that could be ^.{1.6} ignoring blank lines which can’t change). So again the requirements for this challenge were important.

Update!

I came across a neat little unix utility I didn’t know about called “cut”. As you can see, the new command tops the list quite handily too. “cut -c 7-” is actually cutting from each line the 7th character onwards (counting starts from 1). In this case once it spits what it cuts out to stdout; so it leaves behind those first 6 characters and therefore accomplishes our goal. In the above list I removed the optional space after “-c” to make it just a tad shorter. Pretty neat.

Then I found “colrm” which is the most straightforward. This one wins in simplicity. No hacks, just straightforward does exactly what you think it does. Very cool.

Double Update!

I figured since quite a bit of my rr usage has an empty string for the second argument, I figured it would be okay to throw that in as the default case. So now there is a third usage for rr, which is great for pipes, that just strips something out. That brings rr back up to a tie for first place. Very cool.

Installing Ruby 1.8.7 on Mac OS X 10.5.3

Yah, this week is all about solving problems. I run into a lot of them, but it gives me something to blog about. But hey, if I can spend 20 minutes writing down a solution to a couple hour problem that I had, then I could save you a few hours too.

Problem

Trying to install Ruby 1.8.7 (or even 1.9) on my Leopard machine produces warning messages on “make” that look like this:

gcc -I. -I../../.ext/include/i686-darwin9.1.0 -I../.././include
-I../.././ext/readline -DRUBY_EXTCONF_H=\"extconf.h\"    -fno-common
-g -O2 -pipe -fno-common   -o readline.o -c readline.c
readline.c: In function 'filename_completion_proc_call':
readline.c:659: error: 'filename_completion_function' undeclared
(first use in this function)
readline.c:659: error: (Each undeclared identifier is reported only once
readline.c:659: error: for each function it appears in.)
readline.c:659: warning: assignment makes pointer from integer without a
cast
readline.c: In function 'username_completion_proc_call':
readline.c:684: error: 'username_completion_function' undeclared
(first use in this function)
readline.c:684: warning: assignment makes pointer from integer without a
cast
make[1]: *** [readline.o] Error 1
make: *** [all] Error 1

Solution

I originally came across this problem right around new years and eventually found a solution thanks to Han Kessels on the Ruby Forums. It involved the following steps:

  1. Download the newest version of readline (version 5.2 at the time of writing) at GNU.org. You may have to apply the following patch. Thanks to Michael Biven for showing a nice simple way to do this from the command line:

    $ curl -O ftp://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz
    $ tar xzvf readline-5.2.tar.gz
    $ cd readline-5.2
    $ curl -O http://ftp.gnu.org/gnu/readline/readline-5.2-patches/readline52-012
    $ patch -p0 < readline52-012
    $ ./configure --prefix=/usr/local
    $ make
    $ sudo make install
    $ cd ..
  2. Now you can download the 1.8.7 version of ruby, and install it but you should point to the version of readline that you just installed (to /usr/local) like so:

    $ curl -O ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz
    $ tar xzvf ruby-1.8.7.tar.gz
    $ cd ruby-1.8.7
    $ ./configure --prefix=/usr/local/ruby1.8.7 --with-readline-dir=/usr/local
    $ make
    $ sudo make install
    $ cd /usr/local/ruby1.8.7/bin
    $ ./ruby -v
    ruby 1.8.7 (2008-05-31 patchlevel 0) [i686-darwin9.3.0]

The End Result

If you followed my terminal commands from above you should have a working Ruby 1.8.7 version installed in your "/usr/local/ruby1.8.7/bin". If you wanted ruby in a different directory then change the "--prefix=/usr/local/ruby1.8.7" option on ./configure to instead point to the directory you wanted it.

Why put it in its own directory at all? Well, I happen to have multiple version of ruby. By default I have 1.8.6, I have this version of 1.8.7, I even have a 1.9 version I installed a while ago. Its easy to remember where each is if the directory they reside in clearly states the name. This way I can test a script, maybe even run benchmarks, in each version of ruby. However, you might not want to take this extra measure.

Dot Files For Your Shell and Even Ruby

I have come across a number of programmers who don’t know what dotfiles are. Thats a shame. Every programmer should know common dotfiles and actively seek to add aliases, functions, and other tidbits to increase their productivity and make the shell more usable. I recently went on a binge and updated a few of my dotfiles. I’ll share some useful tricks that I found on not only my ~/.bashrc file but also ~/.irbrc for my ruby IRB prompt!

I won’t show off my entire ~/.bashrc file, only because it is rather long. I just want to get across some of the usefulness of such a file:

# -----------
#   General
# -----------
alias ..='cd ..'
alias ll='ls -lh'
alias la='ls -la'
alias ps='ps -ax'
alias du='du -hc'
alias cd..='cd ..'
alias more='less'
alias mkdir='mkdir -p'
alias today='date +"%A, %B %d, %Y"'
alias yest='date -v-1d +"%A %B %d, %Y"'
alias recent='ls -lAt | head'
alias ebashrc='mate ~/.bashrc'
alias mbashrc='mate ~/.bashrc'
alias sbashrc='source ~/.bashrc'
alias htdocs='cd /Applications/MAMP/htdocs/'
alias mampmysql='/Applications/MAMP/Library/bin/mysql -u XXXXX -p'
alias desktoptopia='open /Users/joe/Library/Application\ Support/Desktoptopia/.Backgrounds/'
alias ql='qlmanage -p "$@" >& /dev/null' # Quick Look alias

# -------------
#   Shortcuts
# -------------
alias c="clear"
alias m="mate"

# --------
#   SSHs
# --------
alias rit="ssh holly.cs.rit.edu -l XXXXX"
alias vega="ssh vega.it.rit.edu -l XXXXX"

# -------
#   Git
# -------
alias ga='git add'
alias gs='git status'
alias gd='git diff'
alias github="open \`git config -l | grep 'remote.origin.url' | sed -En 's/remote.origin.url=git(@|:\/\/)github.com(:|\/)(.+)\/(.+).git/https:\/\/github.com\/\3\/\4/p'\`"

# --------
#   Ruby
# --------
alias irb='irb -r irb/completion -rubygems'

# ---------------
#   Environment
# ---------------
export PATH="$PATH:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin"
export PATH="$HOME/bin/:$PATH"
export HISTSIZE=10000
export HISTFILESIZE=10000
export PAGER=less
export CLICOLOR=1
export EDITOR="/usr/bin/mate -w"

Hopefully this wasn’t too overwhelming. But lets take a look at some of these. There are a bunch of aliases at the top which simply replace the older version? It just makes sense that when you do a ps you really want `ps -ax`. Likewise a few others there are printing disk usage with human readable output.

Nothing completely interesting however everything is extremely useful. I’m cutting my keystrokes in half and getting better output. I have a bunch of more exciting tricks in the rest of my ~/.bashrc. Its not just reserved for aliases and EXPORTS, take this function for example:

# cd directly to a dir and list contents
cdl() {
  if [ "$1" ]
  then builtin cd "$1" && ll
  else builtin cd && ll
  fi
}

Cd to a directory and list the directory. I even reference my ll alias up above to list long. You can take a peek at my entire .bashrc file on dotfiles.org. Lets move on to something you may not have known about. Let me walk you through parts of a nice ~/.irbrc file, which you might want for yourself:

# Load and Start Wirble, a gem to beautify irb
require 'wirble'
Wirble.init
Wirble.colorize

Probably one of the most popular inclusions in a .irbrc file. Wirble is a Ruby gem built for improving the irb interactive ruby console. That means you may also have to ‘require “rubygems”‘ in order for this to work. Take a look at the gem documentation for Wirble to find out more of its capabilities. But that also means you can include a number of other useful rubygems. For instance, what_methods, map_by_method, hpricot, yaml, the list goes on and on. Instead I’m going to point out some other neat additions you can add to your .irbrc!

# Awesome benchmarking function
# Source: http://ozmm.org/posts/time_in_irb.html
def time(times=1)
  require "benchmark"
  ret = nil
  Benchmark.bm { |x| x.report { times.times { ret = yield } } }
  ret
end
alias bench time

# A cool way to index in a hash
# h = { :alpha => 'bet', :beta => 'blocker' }
# h/:beta #=> 'blocker'
class Hash
  def /(key)
    self[key]
  end
end

# Simple regular expression helper
# show_regexp - stolen from the pickaxe
def show_regexp(a, re)
  if a =~ re
    "#{$`}<<#{$&}>>#{$'}"
  else
    "no match"
  end
end

# Convenience method on Regexp so you can do
# /an/.show_match("banana") # => "b<>ana"
class Regexp
  def show_match(a)
    show_regexp(a, self)
  end
end

There, now you’re building some really useful tricks! Check it out. Thanks to a few different sources for those code snippets I can easily benchmark any code run at any number of times. There is a neat way to pull an element from a hash, without having to put [brackets] around the key. Finally, a little helper for regular expressions which is useful every now and then.

But wait, there is more. This time a little more system specific:

# Textmate helper
# Source: http://dotfiles.org/~lattice/.irbrc
def mate *args
  flattened_args = args.map {|arg| "\"#{arg.to_s}\""}.join ' '
  `mate #{flattened_args}`
  nil
end

# Clear
def c
  system('clear')
end

You can now open up TextMate from within irb! I’ve also grown so used to using my ‘c’ alias to clear the terminal prompt that I added the same functionality to irb. Just make sure that you don’t name a variable c!

Now let me blow your mind:

# Why's aorta method to edit an object in YAML, awesome!
# Source: http://rubyforge.org/snippet/detail.php?type=snippet&id=22
require 'yaml'
def aorta( obj )
  tempfile = File.join('/tmp',"yobj_#{ Time.now.to_i }")
  File.open( tempfile, 'w' ) { |f| f << obj.to_yaml }
  system( "#{ ENV['EDITOR'] || 'vi' } #{ tempfile }" )
  return obj unless File.exists?( tempfile )
  content = YAML::load( File.open( tempfile ) )
  File.delete( tempfile )
  content
end

Why is a famous member of the Ruby community. This function here actually takes a Ruby object, exports it as YAML to a file, opens the File for editing, and once saved reloads the file from YAML. Essentially it allows you to edit the contents of an object in YAML. Absolutely amazing, let that stir in your mind for a minute!

Now, I have started building my own library of functions that I have deemed semi-useful but not worthy of turning into a gem. These functions include some simple String extensions like my TXT helpers. I include all these files in a directory and I auto-load them like so:

# Load all my non-test libraries in '~/.util/irb'
util_dir = File.expand_path('~') + '/.util/irb/*'
Dir[util_dir].each do |f|
  require f unless File.basename(f) =~ /\Atest/
end

Notice how I ignore any files starting with “test”. I have gotten into the habit of creating test files for my libraries and the naming convention I use is the exact same as the majority of Ruby developers, you just create a new file called “test_library.rb” to test “library.rb”. Simple yes, and helpful in this case where I want to avoid loading these test files. This means I have all my useful functions pre-loaded whenever I open the irb. I’d like to see what additional stuff you have!

Finally here are links directly to my .bashrc and .irbrc files. Enjoy, and please give me additions!

Ruby Can Help you TXT

I’ve never been a “Txter.” I’d much rather call my friends or have them call me. Its a pain to have to search for this small letters, push keys 1-4 times, search for shift, etc. Its a pain ever time I have to text. Hopefully this will be completely avoided as I consider replacing my iPod Touch with an iPhone this coming week after the WWDC Keynote. Either way I decided to employee Ruby to help me out.

It all started with a simple function to convert phone numbers with letters to their numbered equivalent. For instance converting “555-HELP” to “555-4375″ like so:

# Extend the String Class
class String

  # Converts a phone number with letters to numbers
  # Ex. AAA-FFFF => 222-3333
  def convert_to_phone_number
    letters = 'abcdefghijklmnopqrstuvwxyz'
    numbers = '22233344455566677778889999'
    self.downcase.tr(letters, numbers)
  end

end

puts "555-HELP".convert_to_phone_number # => 555-4357

I decided to take it a step further. Why don’t I have Ruby tell me what I should push to text a string? So with a few modifications, and some studying of my cellphone I came up with the following function, also extending the String class (not shown):


  # Converts the given string to the sequence of
  # numbers that you would need to push to create
  # that string. Shift = *, Space = #
  # Input: "Hello hi"
  # Output: "*44 33 555 555 666 # 44 444"
  def how_to_text
    letters    = 'abcdefghijklmnopqrstuvwxyz '
    numbers    = '22233344455566677778889999#'
    multiplier = '123123123123123123412312341'
    str = ''
    self.each_byte do |char|
      char = char.chr
      if char =~ /[A-Z]/
        str += '*'
        char.downcase!
      end
      str += if letters.include? char
        index = letters.index(char)
        numbers[index].chr * multiplier[index].chr.to_i
      else
        char
      end + " "
    end
    str.chop
  end

  # Converts the given numeric sequence back to
  # a text string.
  # Input: "*44 33 555 555 666 # 44 444"
  # Output: "Hello hi"
  def decode_text
    letters = 'abcdefghijklmnopqrstuvwxyz '
    numbers = '22233344455566677778889999#'
    str = ''
    self.split.each do |part|
      shift = part[0].eql?(?*) ? true : false
      part = part[1,part.length] if shift
      pos = numbers.index(part) + (part.length-1)
      str += if shift
        letters[pos].chr.upcase
      else
        letters[pos].chr
      end
    end
    str
  end

Texting is no longer a burden. I even have a decode function to convert back from the cryptic pattern to its original string. Right now the function is limited to typing lowercase letters, uppercase letters, and spaces. I might spend the time to abstract this even more so you can pass in your phone’s texting “model”, a String/Hash/Object providing such information, and it would use that to generate the keystrokes required to text. For now I’m pleased with what I have.

>> "until next time".how_to_text
# => "88 66 8 444 555 # 66 33 99 8 # 8 444 6 33"

I use tab-autocompletion in my IRB and I load this library from my ~/.irbrc, but if you are really interested you could alias how_to_text to how_to_txt to make it a little more fun. That makes it a little harder on tab-autocompletion though.

Feel free to download and improve it. I’ll keep it out of my GitHub for now and just store it in my free directory:
Download
Test Case

Building a Ruby Gem

With all of my recent interest in Ruby I have been overwhelmed by the number of really awesome rubygems. I have talked about some and I will talk about even more in the future but I felt it would be important to learn how to make my own ruby gem. After all, I’d been using GitHub to update a few people’s gems without really knowing the best way to go about such things. It took longer then I expected to find the right resources for what I wanted but I came across three good articles which pointed me in the right direction:

I’m going to write about what I feel you most likely want to know when creating your first Ruby Gem.

1 File/Directory Structure

Gem File Structure
The most basic structure for a simple ruby gem would be like so:

+ gem_name/
   - History.txt
   - README.txt
   - Rakefile
   + bin/
      - gem_name
   + lib/
      - gem_name.rb
   + test/
      - test_gem_name.rb

This is pretty straightforward but let me explain a little. There is an outermost directory that holds everything. Source files go in lib/, executables go in bin/, and test files will go in test/.

The README.txt is essentially to providing the meta-data, installation instructions, and basic information that you would want to any person downloading your gem to read. History.txt is the common name for the Changelog.

2 Utilities to Help You

Now don’t go making these directories by hand! As you probably expected there are a number of tools to get this job done for you. These tools are gems themselves and are therefore simple to install and start working with. The two that I would suggest looking at are Hoe and the slightly more advanced newgem which even uses Hoe.

Both tools come with command line utilities that automate building this directory structure. I’ll start with Hoe, which cleverly named their utility “sow”.

$ sow first_project
creating project first_project
... done, now go fix all occurrences of 'FIX'

  FirstProject/Rakefile:9:  # p.developer('FIX', 'FIX@example.com')
  FirstProject/README.txt:3:* FIX (url)
  FirstProject/README.txt:7:FIX (describe your package)
  FirstProject/README.txt:11:* FIX (list of features or problems)
  FirstProject/README.txt:15:  FIX (code sample of usage)
  FirstProject/README.txt:19:* FIX (list of requirements)
  FirstProject/README.txt:23:* FIX (sudo gem install, anything else)
  FirstProject/README.txt:29:Copyright (c) 2008 FIX

That was easy. It setup a structure exactly like the above but with an additional Manifest.txt file that lists all the files. Easy enough. Lets take a look at newgem:

$ newgem new_proj
      create
      create  config
      create  doc
      create  lib
      create  script
      create  tasks
      create  test
      create  tmp
      create  lib/new_proj
      create  History.txt
      create  License.txt
      create  Rakefile
      create  README.txt
      create  PostInstall.txt
      create  setup.rb
      create  lib/new_proj.rb
      create  lib/new_proj/version.rb
      create  config/hoe.rb
      create  config/requirements.rb
      create  tasks/deployment.rake
      create  tasks/environment.rake
      create  tasks/website.rake
      create  test/test_helper.rb
      create  test/test_new_proj.rb
  dependency  install_website
      create    website/javascripts
      create    website/stylesheets
      exists    script
      exists    tasks
      create    website/index.txt
      create    website/index.html
      create    script/txt2html
       force    tasks/website.rake
  dependency    plain_theme
      exists      website/javascripts
      exists      website/stylesheets
      create      website/template.html.erb
      create      website/stylesheets/screen.css
      create      website/javascripts/rounded_corners_lite.inc.js
  dependency  install_rubigen_scripts
      exists    script
      create    script/generate
      create    script/destroy
      create  script/console
      create  Manifest.txt
      readme  readme
Important
=========

* Open config/hoe.rb
* Update missing details (gem description, dependent gems, etc.)

Okay don’t get intimidated. There is a little more meat this time but I know you’re hungry. Now there is a License, some more automation with rake, configuration files for hoe, a directory for a website allowing you to describe your gem, and even some scripts to make working with your ruby gem a little easier. This seems like a great choice for real large scale gem requiring some major testing.

For the purpose of this blog post I’m going to stick to the basics. I’m not doing anything major here. I’ll stick to Hoe and begin reaping my newly sowed gem. The majority of this tutorial will still apply no matter which method you decide to choose.

3 Pre-Development

A few quick items before you dive into development.

If you used Hoe and sow then you can start out by changing all the occurrences of “FIX”. Most are found in the README.txt file and one more in the Rakefile. Fill out these details as you think they should be filled out. Get these minor details out of the way before you start your work.

I would suggest setting up version control right now and making an initial checkin for your project. The choices here are huge but not necessarily critical for your project. I would suggest that you take a look at Git, Subversion, and Mercurial. I’ll be using git, and hosting my project on GitHub. Its all free, easy, and most of all fun! Tutorials for GitHub are available online, its the easiest version control system I have ever used!

Finally, since Hoe works so nicely with RubyForge you will want to setup an account and install the rubyforge gem. That takes only a few minutes. Setting up the RubyForge bundle is pretty straightforward:

# Install and Setup
$ sudo gem install rubyforge
$ rubyforge setup

# (optional) FYI the location of the edit file
$ mate ~/.rubyforge/user-config.yml

# Configure and List
$ rubyforge config
$ rubyforge login
$ rubyforge names

You should be all set to start development on your gem.

4 Gem Basics

Now that you’re setup you can develop like normal. Put your Ruby Modules, Classes, etc. into the lib folder. One thing that you will notice that Hoe did for you is setup a Class with your gem name and it defined a single constant VERSION. This value is important when the time comes to release and later update your gem. Each section has a well defined meaning. Here is what Dr. Nic had to say:

VERSION = X.Y.Z
X = major release number (MAJOR) – not backwards compatible
Y = minor release number (MINOR) – backwards compatible, additional features
Z = patch/bug fix number (TINY) – small bug fixes

Try to keep your versioning conventions uniform with these values. Then when you want to update your gem all you would need to do would be update the VERSION, and follow through with a release.

Make use of rake to automize testing, doc creation and more. I am still just learning rake so I’ll leave most of the discussion of rake for another time. However you should be aware of the following to get a list of all the functions rake can perform:

$ rake -T

5 Create the RubyForge Package

Because you’ve used Hoe all you need to do is have a RubyForge account, the rubyforge gem configured correctly, and your source files all ready to go. Create a new package on Ruby Forge, which you can do like so:

$ rubyforge create_package bogojoker regex_replace
$ rubyforge config
$ rubyforge names

You would replace bogojoker with your group/username and regex_replace with your package name (which will be your gem name). This is also possible to do from the RubyForge website GUI if you can’t get this working.

6 Release (Deploy) the Gem

Once the package is created you can configure Hoe to publish right to Ruby forge by editing your Rakefile:

Hoe.new('regex_replace', Rr::VERSION) do |p|
  p.rubyforge_name = 'bogojoker'
  p.developer('Your Name', 'Your Email')
end

Again notice this time that ‘regex_replace’ would be the name of your package, Rr::VERSION would point to your VERSION constant auto-created when you created your directory with Hoe’s sow, and that your rubyforge_name would be your group/username for RubyForge and this case ‘regex_replace’ would be.

Uploading is now breeze, just do the following:

$ rake release VERSION=1.0.0

Where the version number is the same as the VERSION constant for your gem. Hoe will make use of rubyforge to package and upload directly to RubyForge with little to no problems. Follow this up with:

$ rake publish_docs

7 Problems / Troubleshooting

Remember when I said “little to no problems?” Well, what if you have problems? I’ll cover a few issues I had:

Where is my RubyForge Project?

Once you make an account you actually have to request to create a project and that request will get approved later in the day. You can go through with everything and host the gem on your own gem server or at least make your .gem available using ‘$ rake package’ and taking the .gem inside the newly created pkg/ folder in your gem’s directory. But once your RubyForge project is accepted you can proceed to upload using ‘$ rake release …’.

no <group_id> configured for <bogojoker>

Make sure you create the package on RubyForge and make sure it goes through. Run the rubyforge create_package command, then config, and names to see if the new package was created. Try a more unique name if it appears not to work.

no <processor_id> configured for <Any>

In this case something went wrong with your rubyforge config. Its not known to me why this may have happened but a few others have had the same problem. The solution is easy, edit the “processor_ids:” in your your ~/.rubyforge/auto-config.yml file to be the following:

processor_ids:
  IA64: 6000
  Any: 8000
  AMD-64: 1500
  PPC: 2000
  Sparc: 4000
  Other: 9999
  i386: 1000
  Alpha: 7000
  MIPS: 3000
  UltraSparc: 5000

Finally:

$ gem install regex_replace
Bulk updating Gem source index for: http://gems.rubyforge.org/
ERROR:  could not find regex_replace locally or in a repository

I thought I had it! Well, actually I did! It just took about 5 minutes for the my gem to be picked up and indexed. So just a few minutes later it was working! If you ever want to search the gem index you can use the following command:

$ gem search -r regex

*** REMOTE GEMS ***

Bulk updating Gem source index for: http://gems.rubyforge.org/
cnuregexp (1.0.0)
regex_replace (1.0.0)
regexbuilder (0.0.1, 0.0.0)
regexp-engine (0.9, 0.8)
RegexpBench (0.5.2, 0.5.1, 0.5.0)
TextualRegexp (1.8.6)

Where ‘-r’ stands for remote and ‘regex’ would be replaced with your search term.

8Conclusions

Rubygems are part of the reason for Ruby’s massive appeal. I can download and make use of incredible ruby libraries or programs with simple ‘gem install’ commands. Now that I’ve produced my own gem I have a greater appreciation for the developers that have made this so streamlined, efficient, and easy.

I think all Ruby Developers should take the time to produce a gem. Why?

  1. Release open source code and contribute to the Ruby community
  2. It will help you when you want to work on someone else’s code
  3. Facilitates a test-driven mindset with rake
  4. Work with the automatic documentation to improve the code you release
  5. Spur creativity. Some Ruby gems are just brilliant. I wanna see more.

I hope this helps you and encourages you to spend the time to publish some of your useful Ruby code so that others like my self can start using it.

I almost forgot, you can grab my gem, which installs the rr command in your bin by running the following:

$ sudo gem install regex_replace

$ rr
usage: rr [options] find replace [filenames]
       rr [options] s/find/replace/ [filenames]

Cheers.

search