---
title: totally classless
teaser:
tags: web,ruby
author: Jared Carroll
published_on: 2007-11-20
---

Recently I had a requirement on an app that had 2 types of groups.

1. public
1. private

Anyone can join a public group.

However to join a private group you have to be registered on the private group's
website, e.g. pretend Yahoo is a private group, now in order to join the Yahoo
group you have to have an account with Yahoo.

Let's pretend that every private group's website implements a simple <abbr
title="Application Programming Interface">API</abbr> that says if the given
username/password is registered with that website.

I'm going to write a client for the <abbr title="Application Programming
Interface">API</abbr> and put it in a module in `lib`.

In `lib/api_client.rb`:

```ruby
module ApiClient
  def authenticate(username, password)
    # make HTTP GET request to the private group's
    # website's API implementation URL
    # true/false return values
  end
end
```

I'll use this library in my `Membership` model during a validation callback on
create.

```ruby
class Membership < ActiveRecord::Base

belongs_to :user
belongs_to :group

include ApiClient

attr_accessor :username, :password

def validate_on_create
  unless authenticate(username, password)
    errors.add_to_base "You are not registered with this group's website"
  end
end

end
```

Here we mix in the `ApiClient` module and use its `#authenticate` method to
validate this membership's username and password (username and password were
added as virtual attributes using `attr_accessor` since I don't want to store
this remote site's credentials in my apps db).

The problem I have with this implementation is that the `#authenticate` method
that gets mixed into `Membership` via `ApiClient` is now a public instance
method on `Membership` and can therefore be used anywhere.  But `#authenticate`
should **only** be used during validation during creation.

```ruby
membership = Membership.find :first
membership.authenticate
```

That's no good.  It's polluting my `Membership` public interface.

Let's try something else in our `Membership` model.

```ruby
class Membership < ActiveRecord::Base

  belongs_to :user
  belongs_to :group

  attr_accessor :username, :password

  def validate_on_create
    api_client = Object.new
    api_client.extend ApiClient
    unless api_client.authenticate(username, password)
      errors.add_to_base "You are not registered with this group's website"
    end
  end

end
```

Here I created an instance of `Object`, mixed `ApiClient` in just that instance
and then used it to `#authenticate` the username/password.  This is an example
of per-object behavior and it gives me exactly what I want.  I don't pollute the
public interface of `Membership` and yet still get to have my remote <abbr
title="Application Programming Interface">API</abbr> behavior all in one place,
`ApiClient`.

Can we shorten `#validate_on_create` a little more?

```ruby
def validate_on_create
  api_client = returning(Object.new) {|instance| instance.extend ApiClient}
  unless api_client.authenticate(username, password)
    errors.add_to_base "You are not registered with this group's website"
  end
end
```

Oh man, an excuse to use the method all the cool kids are using, `#returning`.
I might keep that.  As long as it doesn't go longer than my 80-column character
limit but its already starting to push it!

The final implementation of this feature is an example of per-object behavior.
A style similar to coding in JavaScript.

When the Rails guys tried to make JavaScript more Ruby-like in their prototype
library they added a method to the Object constructor function named `#extend`
to do the very same thing as Ruby's Object#extend.

The above example might look like this in JavaScript.

```javascript
var ApiClient = {
  authenticate : function () {
    // make XML HTTP GET request to the private group's website
    // API implementation URL
    // true/false return values
  };
};

function validateOnCreate () {
  var apiClient = new Object();
  Object.extend(apiClient, ApiClient);
  if (! apiClient.authenticate()) {
    // add/display errors
  }
}
```

David A. Black recently spoke about this at RubyConf 2007.  In his [slides] he
mentions how most Ruby programmers already use it when using class methods and
how its also useful as a way to avoid changing core Ruby.  Dave Thomas mentioned
per-object or <abbr title="Object Oriented Programming">OOP</abbr> without
classes at RailsConf 2007 as well.

[slides]: http://www.ruby-east.com/rubyeast/docs/black-PerObjectBehavior.pdf

Both of these guys got my interest in removing classes from OOP; before them all
I'd seen of this technique was the language Self and its descendant JavaScript.
Anyway enough bs, its an interesting technique and one I'm going to monitor to
see if I see myself moving more and more in this direction.
