Wednesday, April 21, 2010

Passing Classes as Parameters

I've been playing around with genetic algorithms again and I'll post my work a bit later. But, I did realize something while I was doing it that I thought was interesting and completely makes sense, but I hadn't seen discussed anywhere before (that I remember anyway). You can actually pass Classes as parameters to methods, including initializers. Why's this interesting? It allows you to create factories and then pass those factories to other classes. Here's a very simple example, using my genetic algorithm terminology of Organisms.

# Create a basic organism.
class Organism
def speak
puts "I'm a basic organism"
end
end

# Derive an organism that modifies the speak method.
class OrganismOther < Organism
def speak
puts "I'm another organism"
end
end

# Create a "factory" that take a Class as a parameter and can
# generate organisms of that class.
class OrganismFactory
def initialize(organism_class)
@organism_class = organism_class
end

def generate_organism
@organism_class.new
end
end

if __FILE__ == $PROGRAM_NAME

# Create a basic and other factory for the two types of organisms.
organism_factory_basic = OrganismFactory.new(Organism)
organism_factory_other = OrganismFactory.new(OrganismOther)

# Generate an organism of each type.
organism = organism_factory_basic.generate_organism
organism_other = organism_factory_other.generate_organism

# Let them speak.
organism.speak
organism_other.speak
end



You can see that we create a basic Organism and then subclass it to get a slightly different organism. There's nothing too awfully interesting there. Next is the OrganismFactory where we show off our new technique. The initialize() method takes a Class as a parameter and saves it away in the @organism_class variable. We also have a method generate_organism() that will return an object of the type that was passed in. Finally, we have the main program that creates a couple of factories, one of each type, and then uses them to create objects of each type. Finally, we make sure they work by having them "speak".

Let me know if you have questions or comments on this.