Fork me on Github s

Posts Tagged ruby

Zune API Library for Ruby

Those of you who know me, know my favorite music player is the Zune.

For some reason it seems most of my spare time lately seems to be creating Zune API libraries for different languages (I have a PHP one as well).  Here’s another one for Ruby!  If you use it, let me know.  I would love to hear what people are working on.

It’s hosted at github, and very easy to use.

zune_card = Zune::ZuneCard.for('a_zune_tag')

Checkout the README for deets on what fields the object will have.

Tags: , ,

No Comments

Naming your unit tests

When you create a test for your class, what kind of naming convention do you use for the tests? How thorough are your tests? I have lately switched from the conventional camel case test names to lower case letters with underscores. I have found this increases the readability and causes me to write better tests.

A simple utility class:


public class ArrayUtils {

  public static < T > T[] gimmeASlice(T[] anArray, Integer start, Integer end) {
    // implementation (feeling lazy today)
  }

}

I have seen some people who would write a test like this:


public class ArrayUtilsTest {

  @Test
  public void testGimmeASliceMethod() {
    // do some tests
  }
}

A more thorough and readable test would be:

public class ArrayUtilsTest {

  @Test
  public void gimmeASlice_returns_appropriate_slice() {
    // ...
  }

  @Test
  public void gimmeASlice_throws_NullPointerException_when_passed_null() {
    // ...
  }
  
  @Test
  public void gimmeASlice_returns_end_of_array_when_slice_is_partly_out_of_bounds() {
   // ...
  }

  @Test
  public void gimmeASlice_returns_empty_array_when_slice_is_completely_out_of_bounds() {
    // ...
  }
}

Looking at this test, you have no doubt what the method is supposed to do. And, when one fails, you will know exactly what the issue is.

Tags: , , ,

No Comments

Build & Install Ruby Gems with Rake

Are you using rake to build your gems?  Have you ever wished there were an install task to install it to your machine?  I, for one, have written something like this a few times:


desc 'Install the gem'
task :install do
  exec 'gem install pkg/goodies-0.1.gem'
end

That is pretty straightforward.  However, this will not work under JRuby on Mac where the command should be ‘jgem’.  So we can enhance it to detect the platform, and host OS:


desc 'Install the gem'
task :install do
  executable = RUBY_PLATFORM[/java/] && Config::CONFIG[/darwin/] ? 'jgem' : 'gem'
  exec "#{executable} install pkg/goodies-0.1.gem"
end

This is a little better.  I am still not comfortable with the sloppiness of building a shell command and executing it though.  It is possible to do it with strictly Ruby.  I am also going namespace it to integrate better with the GemPackageTask.  Now it will be accessed via ‘rake gem:install’


desc 'Install the gem'
namespace 'gem' do
  task :install do
    Gem::Installer.new('pkg/goodies-0.1.gem').install
  end
end

I have included this in the goodies gem 0.2, so go ahead and install it!  ‘gem install goodies’

Tags: , , ,

No Comments

Make your code gooder with the goodies gem

I have decided to publish all my Ruby tools via a gem called ‘goodies’. 

To install this gem simply type ‘gem install goodies’.

The source is hosted on GitHub.  The first version (0.1) has the Hash object accessors and the String file path utility methods discussed in the previous two posts.

Enjoy!

 

Ruby Goodies @ GitHub
Goodies on gemcutter.org

Tags: ,

No Comments

Clean file separators in Ruby without File.join

I love anything that can be done to clean up source code and make it more readable.  So, when I came upon this post, I was pretty excited.  This is precisely the kind of thing I love.

I have never felt good about ‘file separator’ strings b/c of their ugliness and verbosity.

In Java we have:

String path = "lib"+File.separator+"etc";

And in Ruby a popular method is:

path = File.join("lib","etc")

Now, by overloading the ‘/’ operator on a String in Ruby:

class ::String

  def /(str_to_join)
    File.join(self, str_to_join)
  end

end

We can now write:


path = 'lib'/'src'/'main'

Brilliant!

Tags:

No Comments

Convert your Hash keys to object properties in Ruby

Being a Ruby noob (and having a background in Groovy), I was a little surprised that you can not access hash objects using the dot notation.  I am writing an application that relies heavily on XML and JSON data.  This data will need to be displayed and I would rather use book.author.first_name over book[‘author’][‘first_name’].  A quick search on google yielded this post on the subject.

So, taking the DRYOO (Don’t Repeat Yourself Or Others) concept.  I came up with this:

class ::Hash
  
  # add keys to hash
  def to_obj
    self.each do |k,v|
      if v.kind_of? Hash
        v.to_obj
      end
      k=k.gsub(/\.|\s|-|\/|\'/, '_').downcase.to_sym

      ## create and initialize an instance variable for this key/value pair
      self.instance_variable_set("@#{k}", v)

      ## create the getter that returns the instance variable
      self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})

      ## create the setter that sets the instance variable
      self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
    end
    return self
  end
end

This works pretty well.  It converts each of your keys to properties of the Hash. 

However, it doesn’t sit very well with me because I probably will not use 90% of the properties most of the time.  Why should I go through the performance overhead of creating instance variables for all of the unused ones?

Enter the ‘magic method’ #missing_method:

class ::Hash
  def method_missing(name)
    return self[name] if key? name
    self.each { |k,v| return v if k.to_s.to_sym == name }
    super.method_missing name
  end
end

This is a much cleaner method for my purposes.  Quite simply, it checks to see if there is a key with the given symbol, and if not, loop through the keys and attempt to find one.

I am a Ruby noob, so if there is something I am overlooking, please let me know.

Tags:

14 Comments