Ever get frustrated dealing with files or directories in ruby? Maybe it’s just me, but using File, Dir, FileUtils, Pathname, etc makes me queasy. So I wrote POW! to make life easier.

Git it here http://github.com/probablycorey/pow

or sudo gem install pow

Since path manipulation is kind of boring, I’ll just give a few examples of how it’s helped me. Consider this directory structure…

/tmp
  /sub_dir
    /deeper_dir
  /extra_dir
  file.txt
  program
  README

To open a directory


path = Pow("tmp")

Open a file


Pow(:tmp, :sub_dir, :file.txt) do |file|
  # All the stuff you usually do with an open file!
  file.read
end


Check out what’s inside a directory


path = Pow("tmp")
path.each {|child| puts "#{child} - #{child.class.name}!" }

# Output!
# -------
/tmp/README - Pow::File
/tmp/subdir - Pow::Directory
/tmp/sub_dir/deeper_dir - Pow::Directory
/tmp/sub_dir/file.txt - Pow::File
/tmp/sub_dir/program - Pow::File
/tmp/extra_dir - Pow::Directory

Access a file in that directory


# The / operator accepcts symbols, strings or other Pow objects
file = path / :subdir / "file.txt"

# You can also use brackets to access paths
file = path[:subdir, "file.txt"]

Create nested directories


# Great for code generation

Pow("MOAR").create do
Pow("sub_dir").create do
Pow("info.txt").create do |file|
  file.puts "Here is the info you desired!"
end

Pow("README").create_file do |file|
  file.puts "I'm so glad you read this."
end

# Creates directory structure
/MOAR
  /sub_dir
    info.txt
  README

Sort a bunch of files by the modified date


Pow("images").files.sort_by {|file| file.modified_at}

I’ve always enjoyed the ruby convention of using question marks to denote boolean methods. empty?, exist?, any?, alive?, etc… They’re concise and easy to read. I do have one gripe with it, sometimes testing the inverse makes my code read like yoda wrote it.


not sting.empty?
not path.file?
not param.blank?

In rails I use not something.blank? a lot, so creating a not_blank? method wrapper around blank? was a nice simple fix. But I’m lazy and easily give into the temptation of the dark side, so I created a Bizarro Object. Which lets me do this…


# Meaningless examples that prove my point

"".not.empty?       #=> false
"words".not.empty?  #=> true

0.not.zero?         #=> false
1.not.zero?         #=> true

And here is the bit of code that makes it work…


class BizarroObject
  # Since this is a proxy, get rid of every default method
  # Copied from Jim Weirich's BlankSlate class
  # http://onestepback.org/index.cgi/Tech/Ruby/BlankSlate.rdoc
  instance_methods.each { |m| undef_method m unless m =~ /^__/ }

  # Takes an object as a parameter and will invert the return values of all it's methods.
  def initialize(object)
    @object = object
  end

  def method_missing(symbol, *args)
    !@object.send(symbol, *args)
  end
end

class Object
  # This is where the proxy/bizarro object is created
  def not
    BizarroObject.new(self)
  end
end

It’s not optimized, and it’s a little ridiculous, but I love that ruby lets me abuse it like this.

I have a rails project that is too wily for autotest, but I still want a simple way to make sure my tests are passing. Using git hooks is a simple solution to this problem.

Git Hooks?
Hooks (more info here) are little scripts that git triggers after certain commands. They are located in your projects GIT_DIR/hooks directory and are disabled by default. To enable them just chmod +x the hook you want to run.

How is this helpful for testing?
You can run your specs from the GIT_DIR/hooks/pre-commit hook! The script is run every time you call git commit. If the script exits with a non-zero status your changes won’t be committed and you can scurry to fix your specs. Here is a little example of how I’m using in one of my apps


#!/usr/bin/env ruby

html_path = "spec_results.html"

`spec -f h:#{html_path} -f p spec` # run the spec. send progress to screen. save html results to html_path

# find out how many errors were found
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
failures = html.match(/(\d+) failures/)[0].to_i rescue 0
pending = html.match(/(\d+) pending/)[0].to_i rescue 0

if failures.zero?
  puts "0 failures! #{examples} run, #{pending} pending"
else
  puts "\aDID NOT COMMIT YOUR FILES!"
  puts "View spec results at #{File.expand_path(html_path)}"
  puts
  puts "#{failures} failures! #{examples} run, #{pending} pending"
  exit 1
end

The equality methods in ruby confuse me about once a month. So it’s time to permanently embed this information into my brain.

The first confusing part is remembering which object is doing the comparing.


1 == 2
# It makes more sense if you think of it like this
1.==(2)

1 calls it’s method == with the argument 2. I like to think of it as 1 is put in charge of checking if it equals 2. 2 is just along for the ride.The second confusing part is there are several methods that deal with equality but in a slightly different ways.

equal?
Returns true if the object_id’s are equal. Rarely used, and should not be overridden. You can basically forget out it.

a = b = "bob"
a.equal? b # true

a.equal? "bob" # false since the object_id for the literal "bob" is different than will be different

==
The most common equality operator. It is generally used to test the value of objects instead of the object_id’s.

</pre>
string = "bob"

array = [1,2,3]
array == [1,2,3] # true

string == "bob" # true

1 == 1.0 # true

eql?
Just like == but more strict (i.e. returns false for objects are different types.) As far as I can tell, this is only used to compare hash keys. Like the equal? method, you can basically forget about this one.


string = "bob"

string.eql? "bob" # true

1.eql? 1.0 # false since 1 is a Fixnum and 1.0 is a Float

===
Used for case statements. It is full of magic and sprinkled with mystery. This case statement…


case 1

when Numeric then "Number"

when String then "String"

end
# It is equivalent to...
if Numeric === 1 then "Number"

elsif String === 1 then "String"

end

This seems kind of unintuitive since the arguments for === seem to be in the reversed in the case statement. But this technique has more power than greyskull. Check out Regex, Range, and Module to see clever === uses. Also remember a === b may be true, but it’s converse b === a could be false!

Setting up a google sitemap is an easy way to force google to notice your site. A sitemap is just a simple xml file that lists every url you want google to know about.
They are especially useful if…

  • You have dynamic content.
  • Your site is new and google is unaware of it.
  • You use a lot of AJAX or Flash.

You also get the added benefit of seeing where the googlebot looked last, where it encountered errors, and your sites top search keywords.

So it’s helpful, but is it easy to setup? If you’re using Ruby on Rails (or any other ruby based framework) it’s cake!

Step 1: Created a script (RAILS_ROOT/scripts/sitemap)
This script will collect all relevant urls and create a file at RAILS_ROOT/public/sitemap.xml that contains info about each url. For example, let’s pretend we have a site devoted to hippo pictures, our script would look like this…


#!/usr/bin/env ruby

ENV['RAILS_ENV'] ||= "production"

Dir.chdir(File.expand_path(File.dirname(__FILE__) + "/..")) # Change current directory to RAILS_ROOT
require "config/environment" # Start up rails

# These two lines make life super easy... It allows you to call url_for/link_to outside of a controller or view
include ActionController::UrlWriter
default_url_options[:host] = 'www.hippos-are-awesome.com'

filename = "#{RAILS_ROOT}/public/sitemap.xml"

hippo_pics = HippoPic.find(:all) # Such a wonderful collection

File.open(filename, "w") do |file|
  xml = Builder::XmlMarkup.new(:target => file, :indent => 2)

  # This
  xml.instruct!
  xml.urlset "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do
    for hippo_pic in hippo_pics
      xml.url do
        xml.loc url_for(:controller => "hippos", :id => hippo_pic.id)
        xml.lastmod hippo_pic.updated_at.xmlschema
        xml.changefreq "weekly"
        xml.priority 0.5
      end
    end
  end
end

For more info about what the lastmod, changefreq and priority mean in the sitemap, google explains it all here. Basically they tell google which urls are more important.

Step 2: Create a daily or weekly cronjob to run the sitemap script
Just switch to the user that runs your ruby apps and add this to its crontab.

20 2 * * * PATH_TO_RAILS_APP/script/sitemap # Runs the sitemap script every morning

Step 3: Let google know about your sitemap
Head over to google’s webmaster tools and follow the instructions on how to point google to your sitemap

That’s it. Some other additional things to consider are

  • gzip your sitemap. Google can read them just fine and you save on bandwidth.
  • If you have more than 50,000 links you need to split your sitemap into several files.
  • Other search engines (like yahoo) can take google style sitemaps too.