Jim Neath

Manchester based Ruby on Rails & Facebook App Developer

Showing blog posts tagged as "Ruby"

NGINX is an awesome server, but unfortunately contains an error in earlier versions (pre 0.8.32), that sends the incorrect headers for 201 (created) responses. It does not set the Content-Length header, which causes modern browsers to keep the connection open and wait until the timeout value is exceeded.

There are two possible fixes for this; Upgrade NGINX to version 0.8.32 or greater, or fix the issue in your server side code. I’ll show you how we can do the latter, using Rack.

Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.

We will use a piece of Rack middleware to set the correct headers for any 201 responses.

Copy the code below into lib/content_length_fix.rb:

module Nginx
  class ContentLengthFix
    def initialize(app)
      @app = app       
    end                

    def call(env)
      status, headers, response = @app.call(env)
      headers["Content-Length"] = response.length.to_s if status == 201
      [status, headers, response]
    end                
  end
end

Then add the following to your config.ru file:

require 'content_length_fix' 
use Nginx::ContentLengthFix

Rejoice and your 201 responses now have the correct headers set!

How many times have you looked at some ruby code and found strange variable names (eg. $0, $:, etc) and wondered what they meant? Below is a list of cryptic global variable names in ruby and their meanings.

Environmental Global Variables

$: (Dollar Colon)

$: is basically a shorthand version of $LOAD_PATH. $: contains an array of paths that your script will search through when using require.

>> $: === $LOAD_PATH
=> true
>> $:
=> [".", "/Users/jimneath/.ruby"]
>> $: << '/test/path' # Add a directory to load path
=> [".", "/Users/jimneath/.ruby", "/test/path"]

$0 (Dollar Zero)

$0 contains the name of the ruby program being run. This is typically the script name.

example.rb
puts $0
Jims-MacBook-Pro:~/Desktop ruby example.rb
example.rb
Jims-MacBook-Pro:~/Desktop irb
>> $0
=> "irb"

$* (Dollar Splat)

$* is basically shorthand for ARGV. $* contains the command line arguments that were passed to the script.

example.rb
puts "$*: " << $*.inspect
puts "ARGV: " << ARGV.inspect
Jims-MacBook-Pro:~/Desktop ruby example.rb hello world
$*: ["hello", "world"]
ARGV: ["hello", "world"]

$? (Dollar Question Mark)

$? returns the exit status of the last child process to finish.

>> `pwd` # Show current directory
=> "/Users/jimneath/Desktop\n"
>> $?
=> #<Process::Status: pid=17867,exited(0)>
>> `fake command` # This will fail
(irb):7: command not found: fake command
=> ""
>> $?
=> #<Process::Status: pid=17871,exited(127)>

$$ (Dollar Dollar)

$$ returns the process number of the program currently being ran.

Jims-MacBook-Pro:~/Desktop irb
>> $$ # Show process id
=> 17916
>> puts `ps aux | grep irb`
jimneath 17919   0.0  0.0   599780    388 s000  R+    2:51PM   0:00.00 grep irb
jimneath 17917   0.0  0.0   600252    680 s000  S+    2:51PM   0:00.01 sh -c ps aux | grep irb
jimneath 17916   0.0  0.6    85336  12568 s000  S+    2:51PM   0:00.75 irb

Regular Expression Global Variables

$~ (Dollar Tilde)

$~ contains the MatchData from the previous successful pattern match.

>> "hello world".match(/world/) === $~
=> true
>> $~
=> #<MatchData:0x12be0e8>
>> $~.to_a
=> ["world"]

$1, $2, $3, $4 etc

$1-$9 represent the content of the previous successful pattern match.

>> "hello world".match(/(hello) (world)/) 
=> #<MatchData:0x12b06f0>
>> $1
=> "hello"
>> $2
=> "world"
>> $3
=> nil

$& (Dollar Ampersand)

$& contains the matched string from the previous successful pattern match.

>> "the quick brown fox".match(/quick.*fox/)
=> #<MatchData:0x129cc40>
>> $&
=> "quick brown fox"

$+ (Dollar Plus)

$+ contains the last match from the previous successful pattern match.

>> "the quick brown fox".match(/(quick) (brown) (fox)/)
=> #<MatchData:0x1294a04>
>> $~.to_a
=> ["quick brown fox", "quick", "brown", "fox"]
>> $+
=> "fox"

$` (Dollar Backtick)

$` contains the string before the actual matched string of the previous successful pattern match.

>> "the quick brown fox".match(/quick.*fox/)
=> #<MatchData:0x12882cc>
>> $&
=> "quick brown fox" # The matched string
>> $`
=> "the " # The text preceding the matched string

$’ (Dollar Apostrophe)

$' contains the string after the actual matched string of the previous successful pattern match.

>> "the quick brown fox".match(/quick/)
=> #<MatchData:0x1280c48>
>> $&
=> "quick" # The matched string
>> $'
=> " brown fox" # The text following the matched string

Exceptional Global Variables

$! (Dollar Bang)

$! contains the Exception that was passed to raise.

>> 0 / 0 rescue $!
=> #<ZeroDivisionError: divided by 0>

$@ (Dollar At Symbol)

$@ contains the backtrace for the last Exception raised.

>> 0 / 0 rescue puts $@
(irb):16:in `/'
(irb):16:in `irb_binding'
/usr/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'
/usr/local/lib/ruby/1.8/irb/workspace.rb:52
=> nil

Any More Cryptic Global Variables?

Let me know if I’ve missed any off the list and I’ll get it updated.

Tagged with

I am available for freelance work! Click here to email me.

Jim Neath is a Freelance Ruby on Rails & Facebook app developer from Manchester, UK, currently working for Engine Yard.