Posts Tagged ‘profiler’

require 'profile'

The Profile concept is pretty common in web applications. To define a Profile class, a Ruby developer usually creates a profile.rb file in its lib directory.

# profile.rb
class Profile
end

To use this class in a executable script, we can add the lib path in the Ruby load path and then require all files without having to always specify the absolute or relative path of the file we want to load.

#!/usr/bin/env ruby
# my_app
 
# Add the 'lib' directory in the Ruby load path
$: << File.expand_path File.join(File.dirname(__FILE__), '..', 'lib')
 
# Load the Profile class
require 'profile'
 
# Check that the Profile class has been loaded
puts 'The Profile class is not loaded' unless defined? Profile

We end up with the following directory structure:

my_app/
  bin/
    my_app
  lib/
    profile.rb

Execute the my_app script and you’ll see this:

The Profile class is not loaded
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.00     0.00      0.00        2     0.00     0.00  IO#write
  0.00     0.00      0.00        1     0.00     0.00  Kernel.puts
  0.00     0.01      0.00        1     0.00    10.00  #toplevel

Not only our shiny new Profile class is not loaded, but also some profiling stuff are written to STDERR.

The problem is that a profile.rb file is already defined in the Ruby distribution. If you use the Ruby distribution provided by Leopard, check this file: /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/profile.rb.

require 'profiler'
 
END {
  Profiler__::print_profile(STDERR)
}
Profiler__::start_profile

It starts the Ruby profiler and shows the result at the end of the program -pretty cool BTW-.

To solve this problem, you have to insert you library directories at the beginning of the Ruby load path. That’s what Ruby gems do. Or you can make sure that you always require files by their complete path.

Make a choice for your whole project, because the require statement will load files twice if you do not always give it the same paths. Example:

# Load the Profile class
require 'profile'
# The 'profile.rb' file is read a second time.
require '/home/marcel/code/my_project/lib/profile'

Loading the same class multiple times can be dangerous if you use aliasmethodchain. It will create an infinite loop.