Archive for 2007

Contrasting Python and Ruby

{Thursday, May 3rd, 2007}

Admittedly I’ve been caught in the community currents moving towards Ruby and Rails development triggered by the Pragmatic Programmers. While on the ride I’ve been weary of their seemingly direct competitors, Python and Django.
The choice of which to use has usually been an emotion charged debate.

While others have poked around and performing comparisons, I thought I’d take a quick look for myself.
There are two comparisons at play here which I’ll split into two entries: Python vs. Ruby, Django vs. Rails.

Here’s my take on Python vs. Ruby. Granted it’s a long way off comprehensive, biased by my knowledge of Ruby.

Ruby

Pro’s

  • Everything is an object
  • Method discovery built into the language
  • Language reads more naturally, take optional parenthesis as an example
  • ! and ? methods suffixes are a nice standard for communicating intent
  • return optional
  • More object focused
  • Often more readable
  • IntelliJ IDE support :)

Con’s

  • Slower
  • Less Mature

Python

Pro’s

  • Blocks via indentation more terse
  • Class methods can be easily treated as function objects
  • No need for @, @@, $ as namespaces are used
  • Method arguments can be passed by name
  • Automatically generates compiled scripts for efficiency

Con’s

  • pass required for empty blocks
  • Parenthesis required on method calls
  • self required as first argument to methods
  • return required
  • Verbose import statements, e.g. from package.subpackage.module import class, class.method.
  • Why import an individual method or variable?!
  • Is from datetime import datetime DRY?!
  • Less object focused, attributes are also first class citizens
  • Method documentation (docstring) within method doesn’t aid readability
  • Method default values are only evaluated once and reused in subsequent calls
  • Non-OO approach to sequence manipulation and list comprehensions with methods such as map, del, sort and sorted
  • Dictionaries throw an exception when key not found
  • No concept of scope, class internals completely exposed. Use convention (such as underscore prefix) to suggest scope
  • Ruby has Rake and Python has ?!

Weird stuff

  • zip is an unusual name for iterating over multiple sequences
  • Comparison chaining is unorthodox, i.e. 1 < 2 == 2
  • ‘Isn\’t’ produces the string “Isn’t”. However ‘Isn\’t\”‘ produces the string ‘Isn\’t”‘. In the latter case a backslash remains and the start and end quotes are different.

Similarities

Other discussions of Ruby vs. Python:

The Basics of REST in Rails

{Tuesday, April 24th, 2007}

REST fundamentals

HTTP supports 4 request (method) types:

  • Post: Intended to create a resource
  • Get: Intended to retrieve a resource
  • Put: Intended to update a resource
  • Delete: Intended to delete a resource

However browsers typically only support Post and Get requests. Put and Delete requests have been ignored and fulfilled by abusing Post and Get. The essence of REST lies in considering the web as providing information about resources, it proposes to change the way we view URL’s from actions to requests on a resource. Actions that were once part of the URL (i.e. /products/show/1), are now expressed in the method (HTTP GET /products/1).

Why should I use REST?

The key reasons appear to be:

  • As an alternative to Web Services, Messaging etc. for manipulating a resource
  • A consistent approach to resource discovery

Also consider that the cost of implementing RESTful requests in Rails is no more than conventional requests.

Rails Support

Rails accommodates the lack of browser support for Put and Delete with an additional request parameter that simulates the request type.

routes.rb is the key

The core of Rails’ REST support lies in routes.rb. As always, entries here map URL’s to controllers and actions.
The following entry allows the Product model to be accessed as a RESTful resource.

map.resources :products

These entries also generate methods used to assemble URL’s in views and controllers. Based on the previous example the following methods are generated:

  • products_url, products_path
  • product_url(id|product), product_path(id|product)
  • new_product_url, new_product_path
  • edit_product_url(id|product), edit_product_path(id|product)

They can be used as follows:

  • Link to list all Products
    link_to 'Products', products_path
  • Form for creating a new product
    form_tag(:product, :url => products_path) do
  • Form for editing a product
    form_tag(:product, :url => product_path(@product), :html => {:method => :put}) do
  • Link to delete a Product
    link_to 'Delete', product_path(@product), :method => :delete
  • Performing a redirect to view a Product
    redirect_to product_url(@product)

Controllers respond via respond_to

REST allows clients to request different response types. Controller actions accommodate this using respond_to. Example:

def show
  all_product = Products.find :all
  respond_to do |format|
    format.html
    format.xml render(:xml => all_products.to_xml)
  end
end

To issue a non-HTML RESTful request the URL must be a RESTful URL ending with .<desired type>. For example a XML request should end in .xml (i.e. METHOD GET /products/1.xml).

Scaffold support

Rails scaffolding supports the use of REST:

rake scripts/generate scaffold_resource <name> <field>:<type> <field>:<type>...

This command

  • Creates: model, restful controller, views, migration with columns
  • Edits: routes.rb for RESTful request support

Paying Homage to DDD

{Monday, April 23rd, 2007}

I’ve read Domain-Driven Design (DDD) a couple of times now and consider it the most influential book on the way I develop software. But I’ve yet to blog about it. It’s time to change that.

Firstly, serious developers and analysts simply must read this book. It’s the sort of book I’d demand be read if I owned a software organization, though (being generous) around half of the book is applicable to Analysts.

Before I read DDD the concept of a Domain Model was somewhat fuzzy, even after reading Patterns of Enterprise Application Architecture. So often I’d seen ‘Domain Models’ purely holding state. I’d joined teams late in the game that had developed ‘intelligent’ Domain Models, but how they got there was a mystery. Questions like:

  • Why had this domain concept become a class?
  • Why apply this pattern in the domain layer?
  • What direction are we headed with the domain model?

…the answers were never clear to me. Often one technician on the team had the answer, but I didn’t feel empowered with the knowledge to act without their consultation.

DDD hits home the importance of Domain Models and presents infinitely more information than development guidelines like ‘objects should have both state and behavior related to that state’. My most significant learning from it is an approach for distilling real world concepts into software, concepts that linger in the mind of domain experts but never crossed the divide. I won’t go into detail here, but the book presents the essence of distilling those concepts - unifying the language used across roles and, more generally, throughout the team.

It’s now a rare day when a team member’s ear won’t be ringing to the sound of me stressing the importance of modeling objects on domain principles, rather than abstract, somewhat related or technical ones. Analysts directly contribute to assembling simplified object models and are on the receiving end of questions like ‘does this concept have a name?’, ‘is there a general concept that encapsulates these things?’, ‘can we break this thing down, what do you think it’s composed of?’, ‘how would you identify each of these?’.

From a requirements perspective, it’s shifted my focus from understanding the requirements and acceptance criteria in isolation to understanding the core domain; the business of the users. According to the Kano Quality Model, customers are delighted when they discover new and useful features, stuff they wouldn’t expect to see. Immersion in the domain is key to having this capability.

From a development perspective, it’s given me techniques to aid modeling the domain in software. They focus on keeping the software simple and reducing translation time between the software and the domain. Again, I won’t spell out in detail what’s best covered by the book, but it is the kind of stuff you can start practicing immediately, the majority of it transcends languages and is bound to be relevant for many years.

The book also offers solid advice to leaders on effective team structures and subdividing teams and domains. This ground is probably less explored than other parts of the book but it’s no less important. From my experience it is used less, quite simply, because changes of that magnitude requires organizational clout that is difficult for a team to ascertain.

Here’s a brief list of observations from my DDD experiences:

  • I find myself spending more time thinking, less time doing while at the same time being more productive
  • I’m more proactive in engaging analysts. Emotionally there’s less of a divide between developers and analysts
  • The code is more consistent and easier to navigate. You are less likely to be able identify the code of an individual
  • You fear changes to the code less
  • You strive to the understand the business’ problems more and focus less on simply producing software
  • Design discussions are welcomed and flow naturally, there’s often less friction
  • Breakthroughs, refactorings that significantly simply the implementation, come earlier rather than later

Credit where credit’s due; this book is quite simply an excellent geek read. For more info see Domain-Driven Design.