Archive for the 'Ruby' Category

Writing a Yard Extension To Show Inherited Attributes

April 04th, 2011 | Category: Programming, Ruby

So RDoc is an absolutely terrible documentation generator both from the usage and the coding perspective. Although yard is not yet quite as stable as I’d like, it is everything RDoc is not, it’s pretty, well written, and provides numerous well thought out extension points. So as an exercise I decided to fix one of the more annoying issues with yard as an extension.
Read more

1 comment

Unit, Cucumber, and/or Rspec (DHH Say it ain’t so!)

April 01st, 2011 | Category: Programming, Ruby

So recently, dhh tweeted that he doesn’t really get why cucumber and rpsec are so popular and questioned their benefit outside of a niche audience relative to the high cost of writing with them relative to X-Unit style tests. I’ve used ruby test, rspec, and cucumber extensively and I’m finding it hard to see that point of view.

I think the disconnect may be related to what your perspective is on the use of a unit test. While I think most developers would agree that unit tests are for validating and developing code, I think if that is all you see them for it is essentially like saying that good code is code that performs a task correctly. In both cases there are more factors to consider.

First, tests have to be maintained just like any other code. Unmaintainable tests slow down code refactoring rather than supporting it and as such will generally be discarded and the most useless tests are ones that don’t get run. So at the very least you need to apply the same concepts of readability, maintainability, etc to your tests that you (hopefully) bring to the rest of your code.

A second, and to my mind equally important, use of tests is to document what your system is supposed to do. Large projects with many maintainers and users may not have as much of an issue here. If your framework is covered by thousands of blog articles, books, and examples are widely available then feel free to disregard this advice. For the rest of us, getting as much self-documentation out of a code base as possible should be a major goal.

This is really where both cucumber and rspec outshine XUnit style test frameworks. A cucumber test is a human-readable description of feature of your system that a new coder can read without having to understand the underlying code. Even better, because each statement in the description links to code it provides a direct link between feature documentation and code required to configure, execute, and validate that feature. Finally, error messages have the same level of descriptive context making understanding errors that much easier.

The one point I will concede is that cucumber is not one size fits all. If you are validating an API (as opposed to a product interface like a web page or gui) cucumber is less beneficial because it obscures the API itself and replaces it with human language. In these cases rspec is clearly preferred.

In cases where you are testing the system however cucumber has some clear benefits over rspec:

  • It forces you to think in terms of how the product will be used rather than how it is implemented.
  • It forces you to describe that behavior concisely.
  • It documents the behavior of the system clearly in a way even a non-programmer can understand.
  • By doing all of this it makes maintaining tests much easier even as product feature implementations change because implementation is clearly abstracted from the test script
2 comments

Reopening modules in Ruby

March 31st, 2011 | Category: Programming, Ruby

Open class definitions in ruby allow libraries to add functionality to existing objects. Standard practice is to define a module with the new functionality and include it into the existing class ( Jay fields on the subject here ). Unfortunately this model breaks when you want to update a module.
Read more

1 comment

Why class variables in Ruby are a bad idea

March 20th, 2011 | Category: Programming, Ruby

In ruby, there are instance variables and class variables. Class variables may not work the way you think… Read more

Comments are off for this post

Improving your exception backtrace with Ruby DSLs

February 02nd, 2011 | Category: Programming, Ruby

One issue with a Domain Specific Language in any language is that the error messages from the actual language tend to ruin the illusion of a custom language. In ruby a stack trace with a million “method_missing” calls can be confusing.
So what can you do? Edit and filter the backtrace.
Read more

Comments are off for this post

attr_accessor with default in Ruby

January 31st, 2011 | Category: Programming, Ruby

If you aren’t in rails (hello to both of you) the lack of an attr_accessor with a default value is very annoying. I wrote up the following:

module ExtendAccessors
  def attr_accessor_with_default name, *default, &block
    if(default.size >= 1)
      define_method name.to_sym do
        instance_variable_set("@#{name}", default[0]) unless instance_variable_defined?("@#{name}")
        instance_variable_get("@#{name}")
      end
    elsif block_given?
      define_method name.to_sym do
        instance_variable_set("@#{name}", instance_eval(&block)) unless instance_variable_defined?("@#{name}")
        instance_variable_get("@#{name}")
      end
    else
      raise "Must either provide a default value or a default code block"
    end
    define_method "#{name}=".to_sym do |value|
      instance_variable_set("@#{name}",value)
    end
  end
end

which supports the following syntax:

class A
  extend ExtendAccessors
  attr_accessor_with_default :some_map, {}
  attr_accessor_with_default :some_object do
    AnotherObject.new(self)
  end
end
Comments are off for this post

Meaning of ’self’ in Ruby

January 25th, 2011 | Category: Programming, Ruby

This came up today. When defining classes in Ruby “self” can refer to the class or the instance of that class depending on the context and understanding which is which is important.

When defining a class “self” in the context of the class definition refers to the object representing the class being defined. When in a (non-class-level) method “self” refers to the instance of the object. So:

class SomeClass
  #dynamically add a method to the SomeClass object. 
  #self is the SomeClass class object
  #now I can call SomeClass.class_level_method
  def self.class_level_method
    self == SomeClass #this is true....
  end
 
  #define an instance level method
  def instance_level_method
    self #this is now an instance of the object
  end
end

This syntax may make more sense in terms of the following

class SomeClass
end
 
#this can be done outside of the class definition
def SomeClass.class_level_method
  echo "hi"
end
 
c = SomeClass.new
d = SomeClass.new
 
#class objects are notspecial in this regard. 
#You can do the same thing to
#a specific object instance of any other type.
def c.specific_instance_method
  #this method is defined just for this 
  #specific instance of this class
end
 
c.specific_instance_method #no problem
d.specific_instance_method #nope!
Comments are off for this post

SWIG, Java, and JRuby

July 22nd, 2010 | Category: C++, Java, Networking, Programming, Ruby

Providing a robust, maintainable, and interactive interface to your C/C++ application can be a challenge, but I’ve found that a combination of SWIG, Java, and JRuby (or Jython if you prefer) makes for a very powerful combination.
Read more

Comments are off for this post

A Better Binary File Generator DSL in Ruby

September 13th, 2008 | Category: Programming, Ruby

In Creating a Binary File Using a Ruby DSL I did a very small example of using a ruby DSL to generate complex binary files without having to use C or a hexeditor. I’ve beefed it up significantly since then so here is the updated version of h2b.irb.
Read more

Comments are off for this post

XPath From the Command Line Using Ruby

September 13th, 2008 | Category: Programming, Ruby, XML, XPath

There are other ways of doing this, but I thought it would be fun to write a command-line xpath script in ruby using rexml. (full working example here)
Read more

Comments are off for this post

Next Page »