gem snippets

Find the installation directory of a RubyGem package programmatically

Tagged ruby, rubygems, gem, path, package  Languages ruby

This snippet prints the full path to the Rails installation directory--the path is retrieved using the RubyGems API:

require 'rubygems'
puts Gem.cache.search('rails').first.full_gem_path
# Specify version number
puts Gem.cache.search('rails', '=1.0.0').first.full_gem_path

Example output:

/usr/lib/ruby/gems/1.8/gems/rails-1.0.0

To find the directory where your gems are hiding, use:

gem env

There's also the gem which command:

$ gem which activesupport
(checking gem activesupport-2.3.2 for activesupport)
/opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/activesupport.rb

Error when installing Mongrel from gem

Tagged ruby, gem, mongrel, mkmf (loaderror)  Languages bash

I received the following error when installing Mongrel from the gem repository:

marko@x61s:$ sudo gem install mongrel
Updating metadata for 281 gems from http://gems.rubyforge.org
complete
Building native extensions.  This could take a while...
ERROR:  Error installing mongrel:
    ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb install mongrel
extconf.rb:1:in require': no such file to load -- mkmf (LoadError)
    from extconf.rb:1

The fix is to install the ruby development package:

sudo apt-get install ruby1.8-dev

How to install the stemmer4r gem on Mac OS X and Linux

Tagged stemming, stemmer4r, install, osx, linux, gem  Languages ruby

The stemmer4r gem is fubar. Warning draft snippet...

# gem install stemmer4r
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

ruby extconf.rb install stemmer4r

Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6/ext/stemmer4r/gem_make.out


1. Change path of Ruby executable

cd /usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6/ext/stemmer4r/
vim extconf.rb

#!/usr/bin/ruby -w

to

#ruby -w

2. Compile libstemmer_c

cd /usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6/ext/stemmer4r/libstemmer/
make

3. Compile stemmer4r

cd /usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6/ext/stemmer4r/

Change path:
/usr/local/ruby/lib/ruby/1.8/i686-linux/
To:
/usr/lib/ruby/1.8/x86_64-linux/

Or wherever you have it installed

ruby extconf.rb


4. Build stemmer4r gem


gem build stemmer4r.gemspec

gem install stemmer4r-0.6.gem


Problems

gcc -shared -rdynamic -Wl,-export-dynamic   -L"/usr/lib" -o stemmer4r.so stemmer4r.o libstemmer_c/libstemmer.o  -lruby1.8  -lpthread -ldl -lcrypt -lm   -lc
/usr/bin/ld: libstemmer_c/libstemmer.o(libstemmer.o): relocation R_X86_64_32 against a local symbol' can not be used when making a shared object; recompile with -fPIC
libstemmer_c/libstemmer.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [stemmer4r.so] Error 1


Add CFLAGS:

root@aktagon:/usr/lib/ruby/gems/1.8/gems/stemmer4r-0.6/ext/stemmer4r/libstemmer_c# make
include mkinc.mak
CFLAGS   =  -fPIC
libstemmer.o: $(snowball_sources:.c=.o)
        $(AR) -cru $@ $^

How to profile your Rails and Ruby applications with ruby-prof

Tagged ruby-prof, rails, gem, profiling, benchmark, profile, kcachegrind  Languages ruby

Installing ruby-prof

First install ruby-prof:

git clone git://github.com/jeremy/ruby-prof.git
cd ruby-prof/
rake gem
sudo gem install pkg/ruby-prof-0.6.1.gem

Note that version 0.6.0 doesn't work, at least not with Rails 2.1.1. With 0.6.0 I got this message:

gem install ruby-prof to use the profiler

Setting up a new environment for profiling

Create config/environments/profiling.rb:

config.cache_classes = true
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching             = true
config.action_view.cache_template_loading            = true

#config.log_level = :debug

Add the new environment to database.yml. You might want to reuse the development database.

Creating a profiling script

Next we'll create a script that simply fetches the homepage, save the following code in profiling/homepage.rb:

get '/'
say "GET / => #{path}"

Run the script

Now run the script 100 times:

RAILS_ENV=profiling ./script/performance/request -n 100 profiling/homepage.rb

Profiling plain Ruby applications

You can also profile a block of code by calling RubyProf from your code:

require 'ruby-prof'

# Profile the code
RubyProf.start
...
[code to profile]
...
results = RubyProf.stop

File.open "#{RAILS_ROOT}/tmp/profile-graph.html", 'w' do |file|
  RubyProf::GraphHtmlPrinter.new(results).print(file)
end

File.open "#{RAILS_ROOT}/tmp/profile-flat.txt", 'w' do |file|
  RubyProf::FlatPrinter.new(results).print(file)
end

File.open "#{RAILS_ROOT}/tmp/profile-tree.prof", 'w' do |file|
  RubyProf::CallTreePrinter.new(results).print(file)
end

Analyzing results

I prefer to use the RubyProf::CallTreePrinter to output data that kcachegrind can read. The HTML and text data is difficult to read so kcachegrind will definitely make your life easier.

On OSX you can install kcachegrind with Fink (or DarwinPorts):

sudo apt-get update ; sudo apt-get install fink
sudo apt-get install kcachegrind

There's also WinCacheGrind and MacCacheGrind, but I haven't tried those.

How to fix issues with missing gem specifications

Tagged hpricot, gem, unpack, rails  Languages bash

I was getting this error after unpacking hpricot with gem unpack hpricot. I also tried rake gems:unpack hpricot but it did nothing...

config.gem: Unpacked gem hpricot-0.8.1 in vendor/gems has no specification file. Run 'rake gems:refresh_specs' to fix this.

The rake gems:refresh_specs command doesn't work, and appears to have been a temporary workaround, so to fix this error I did this:

cd vendor/gems/hpricot-0.8.1
gem specification hpricot > .specification

I had this issue with Rails 2.3.4.

Reading gem version from YAML

Tagged gem, rubygem, version, jeweler  Languages ruby

From Jekyll:

module YerGem
  def self.version
    yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])))
    "#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
  end
end