The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
An Observation of How Rack is Affecting Rails

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Rick DeNatale

Posts: 269
Nickname: rdenatale
Registered: Sep, 2007

Rick DeNatale is a consultant with over three decades of experience in OO technology.
An Observation of How Rack is Affecting Rails Posted: May 8, 2009 6:06 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Rick DeNatale.
Original Post: An Observation of How Rack is Affecting Rails
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Rick DeNatale
Latest Posts From Talk Like A Duck

Advertisement

This started out with a question on the RSpec group about why debugger invocations in Cucumber steps seemed to be ignored.

Now, I didn't know the answer to that, but I did have a bit of related knowledge since one of my contributions to RSpec was adding the --debugger/-u option to the spec command as an analog to the same option in the script/server command in Rails. As far as I know that option hasn't been added to Cucumber.

Which led me to refreshing myself on how Rails implements that option in order to help answer the Cucumber question. So I brought up the rails gem in textmate on the latest version of Rails, and had a minor epiphany.

Under the Hood of the script/server --debugger Option

In Rails you can put debugger calls in your code which will cause a debugger breakpoint if you are running with the --debug option, but do nothing (actually it writes an info level entry to the log ) if you aren't.

The latter is pretty easy, during initialization, ActiveSupport asks Kernel if it responds to :debugger, and if not defines the method to do the log.

The other part involves script/server running this code when it starts up if -u or --debugger was one of the command line options:

  begin
    require_library_or_gem 'ruby-debug'
    Debugger.start
    Debugger.settings[:autoeval] = true if Debugger.respond_to?(:settings)
    puts "=> Debugger enabled"
  rescue Exception
    puts "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'"
    exit
  end

And the rspec command does pretty much the same thing since David picked up my contribution a few releases ago.

Rails 2.2 vs Rails 2.3

My epiphany came when I looked at Rails 2.3.1, and didn't have as much of a deja-vu as I expected. The difference is how that code to conditionally install and start the debugger gets executed.

In Rails 2.2, script/server looks at the first argument to determine whether to run mongrel, lighty, thin, or webrick. If that's not specified it goes through some sniff tests to infer which to run.

It then requires a specific server based script to actually run the server. The mongrel and webrick scripts support the debugger option and run the load code if it is specified.

Rails 2.3.1 does things a bit differently. The script/server program parse the options, then loads the debugger with this snippet of code:

app = Rack::Builder.new {
  use Rails::Rack::LogTailer unless options[:detach]
  use Rails::Rack::Debugger if options[:debugger]
  map map_path do
    use Rails::Rack::Static 
    run inner_app
  end
}.to_app

So the debugger is turned on by inserting a rack middleware, what does this look like?

module Rails
  module Rack
    class Debugger
      def initialize(app)
        @app = app

        require_library_or_gem 'ruby-debug'
        ::Debugger.start
        ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings)
        puts "=> Debugger enabled"
      rescue Exception
        puts "You need to install ruby-debug to run the server in debugging mode. With gems, use 'gem install ruby-debug'"
        exit
      end

      def call(env)
        @app.call(env)
      end
    end
  end
end

The code in the initialize method does give me deja-vu!

This is an interesting approach. It's consistent with Rails move to improved configurability using Rack. There's a slight overhead (1 method call per request) due to the passthrough, but that's insignificant in the overall scheme of things, particularly since it's only inserted when you are running with the debugger.

Read: An Observation of How Rack is Affecting Rails

Topic: Rails Conf 2009 Third Day of Sessions Previous Topic   Next Topic Topic: ActionScript, Dogfood and Refactoring

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use