Blog

Saturday, August 21, 2010

A CMS is Not Out-of-the-box Software

This morning I was doing a "Saturday" clean out of some old files and came across this snippet from Namahn regarding Content Management Systems (CMS). I originally came across this around mid-2009:

"Moreover a CMS is almost never a piece of software that comes out-of-the-box. Rather it is a platform/framework for building a custom content application based on an organisation’s needs."

Only for the simplest websites, is a CMS going to work out of the box. I have yet to be involved in a CMS project where there's not some customization required.

"To define the architecture of a CMS and the features it has to offer, you need to figure out how corporate content is created, how it travels through its lifespan, and the uses to which it is put. And because corporate content is created, maintained and used by humans, it is mandatory to define the different interactions people have with documents."

Most of the open source CMS platforms don't address the life cycle of the content. They are good at publishing the content, but never the workflow. Really they should be called Website Publishing Systems (WPS), not Content Management Systems. It would be nice to see more work in this area in the open source realm.

The "white paper" is worth a read if you're trying to get beyond the basics of content management.

Saturday, August 14, 2010

When to use Ruby's class_eval vs. instance_eval

When to use class_eval vs instance_eval? Here are some basic rules to follow:

  1. When the object is a class use class_eval, you will typically be using the def keyword
  2. When the object is an instance use instance_eval

There is an important subtle difference between the two.

  • class_eval changes self and the current class
  • instance_eval only changes self

If you don't need to use def then what should use use? Well you could use MyClass.instance_eval. But as Paolo Perrotta states from Metaprogramming Ruby:

"…pick the method that best communicates our intentions."
class Book
  
  # define a class instance variable
  #
  @books_published = 0

  # define the attr_accessor as a class method
  #
  class << self
    attr_accessor :books_published
  end
    
  def initialize(title)
    @title = title
    Book.books_published =+ 1
  end
end

b = Book.new("Metaprogramming Ruby")

Book.class_eval do
  def introduction
    "Thank you for reading #{@title}"
  end
  
  private
  
  def units_sold
    100_000
  end
end

b.instance_eval do
  puts @title # access an instance variable => Metaprogramming Ruby
  puts units_sold # send a message to a private method => 100000
end

puts b.introduction # => Thank you for reading Metaprogramming Ruby

# I don't care if this is a class or an instance
Book.instance_eval do
  puts @books_published # => 1
end

Wednesday, August 11, 2010

User Story Format

Something I am constantly looking up is a format for user stories. While reading The RSpec Book tonight it remind me to write this down. I thought my blog would be a good place for it.

Connextra Format (named after the company)

As a [stakeholder], I want [feature] so that [benefit].

Popular Variant

In order to [benefit], a [stakeholder] wants to [feature].

Friday, August 6, 2010

Questions asked in a Ruby on Rails Job Interview

Here are some real life Ruby and Rails questions that you maybe asked in a job interview. These are based on my experience in applying for contract positions. I have not provided the answers, I will leave that as an exercise to the reader (as they say).

General Object-Oriented and Programming Questions

  1. What is polymorphism?
  2. What is overriding and oveloading?
  3. What does a test suite contain? (e.g. setup, fixtures, assertions)

Ruby Theory Questions

  1. What is a Singleton Method?
  2. What is the difference between a block, lamda and proc?
  3. What is the super class of Class?
  4. What is the super class of Module?
  5. What is a class variable vs. a constant?
  6. What do you like about Ruby?

Ruby Practical Questions

  1. Print the numbers 1 to 10 in the console
  2. Create a custom method to iterate over an array contain negative and positive numbers and only print the positive numbers

General Algorithm Questions

  1. Reverse an interger, e.g. 12345 => 54321, without converting to a string
  2. Perform a Binary Search on an array of numbers to find a target number

Rails Questions

  1. What is the difference between #destroy and #delete?
  2. What modules make up Rails? (e.g. ActiveRecord)
  3. What is ActiveSupport?
  4. What two extension methods does ActiveSupport contains?
  5. What association methods does ActiveRecord provide?
  6. Which table is the foreign key related in a belongs_to association?
  7. What annoys you about Rails?
  8. Describe a situation where you had to work outside of the Rails stack or customize Rails  to make it meet project requirements?

Database Questions

  1. What is an index?
  2. How is an index implemented?
  3. When would you use an index?
  4. What are the first things to look at with a slow query containing a join?
  5. What is an outer right join?

These questions are ones that I have been asked personally. Please add questions you have been asked in the comments. I'm sure there are some I am missing so I will update this post as they come to mind.

 

Wednesday, July 7, 2010

Ruby's Object#try method

Yesterday I blogged about implicitly testing for nil, relying on Ruby's definition of truth, rather than the explicit Object#nil? to keep code terse.

Here's another example of keeping code terse when handling nil values with Object#try. This is particularly helpful when working with ERB:

# in ERB template
@order.user.name if order.user
The simplified version:
# in ERB template
@order.user.try(:name)

Something I didn't know previously to writing this post, is Object#trysupports arguments similar to Object#send.

Object#try was added to ActiveSupport in Rails 2.3.2.

Monday, July 5, 2010

Keeping your code terse, testing for "nil"

On a recent project, I was seeing many occurrences of this statement:

if !order.user.nil?
  # do something ...
end

While this is correct, it's not idiomatic Ruby. Ruby is a terse language. Let's keep our code terse as well. Consider how Ruby defines truth:

"Ruby has a simple definition of truth. Any value that is not nil or the constant false is true." (Agile Development with Rails, 3rd Edition, pg 319).

This means testing for "nil" is redundant. We can therefore shorten our code to:

if order.user
  # do something ...
end

Nice and clean.

Thursday, May 27, 2010

Email to a Friend: Where to start with Agile Development

Recently a friend emailed me asking how to get started with an agile development methodology. This was my reply (after a little editing to make it more "blog friendly"):

User Stories are the Foundation

For me personally, the foundation of agile is working with user stories. You must have a clear understanding of what user stories are. I would recommend checking out Use Stories Applied by Mike Cohen. This will give you a great foundation. From an estimation point of view, you might want to consider Agile Estimating and Planning by the same author. But not a requirement.

Choose a Methodology

If you’re going to use Scrum (I see that you mentioned “sprints”), to get a good understanding of the lingo and how to plan sprints etc, read Agile Software Development with Scrum

These books should give you a good foundation. They are easy read and not 400 page tombs. You should be able to get throw one in a weekend. They are based on agile after all so they shouldn’t be lengthy reads!

Get Customer Buy-in

The most important thing is that you will need to get buy in from everyone involved. “Agile Software Development with Scrum” provides some good information on this. Maybe a presentation on Scrum would be a good idea to get buy-in. Definitely choose a specific methodology and then customize as required. Since you have no experience, you need a path to follow, and you might run into trouble “just doing agile”. Having a specific methodology (probably not the best noun to use when talking about agile) will be rest assuring to the team.

Make Progress Visible

Of course, the most part is visibility. You want to be able to show visible progress early compared to traditionally managed projects. This comes in deliverables, but also what the priorities are and what people are working on right now. Don’t get too eager to deliver something too quickly. I like Scrum, because sprints are traditionally 30 days, and you never get anything substantially done early than that. Having said that, these guys got something up and running in a week.

If everybody is on site, then a war room with user stories pinned to the wall is a good start; this would be my preference. Otherwise you can use tools such as PivotalTracker or one of the new kids on the block AgileZen.

Manage User Stories

Managing a large collection of user stories is difficult. I think the concept of a story map is a great way to organize them. It gives structure to a loose collection or requirements, which builds confidence all round.

Conclusion

So in conclusion;

  • understand user stories,
  • organize them with a story map,
  • have a war room,
  • use remote user story tools only if required,
  • choose a specific agile methodology (try Scrum),
  • manage expectations.

And remember, make sure you are really doing agile, as it only works if you have all the pieces working together, such as customer buy-in.

Manage expectations, it will take a sprint or two before you are comfortable with the process.

Please note this blog is no longer maintained. Please visit CivilCode Inc - Custom Software Development.