Programming Ruby: The Pragmatic Programmer's Guide

# Programming Ruby ### The Pragmatic Programmer's Guide
Previous < | Contents ^ | Next >

# Classes, Objects, and Variables

From the examples we've shown so far, you might be wondering about our earlier assertion that Ruby is an object-oriented language. Well, this chapter is where we justify that claim. We're going to be looking at how you create classes and objects in Ruby, and at some of the ways in which Ruby is more powerful than most object-oriented languages. Along the way, we'll be implementing part of our next billion-dollar product, the Internet Enabled Jazz and Blue Grass jukebox.

After months of work, our highly paid Research and Development folks have determined that our jukebox needs songs. So it seems like a good idea to start off by setting up a Ruby class that represents things that are songs. We know that a real song has a name, an artist, and a duration, so we'll want to make sure that the song objects in our program do, too.

We'll start off by creating a basic class `Song`,[As we mentioned on page 9, class names start with an uppercase letter, while method names start with a lowercase letter.] which contains just a single method, `initialize`.

    class Song
      def initialize(name, artist, duration)
        @name     = name
        @artist   = artist
        @duration = duration
      end
    end

`initialize` is a special method in Ruby programs. When you call `Song.new` to create a new `Song` object, Ruby creates an uninitialized object and then calls that object's `initialize` method, passing in any parameters that were passed to `new`. This gives you a chance to write code that sets up your object's state.

For class `Song`, the `initialize` method takes three parameters. These parameters act just like local variables within the method, so they follow the local variable naming convention of starting with a lowercase letter.

Each object represents its own song, so we need each of our `Song` objects to carry around its own song name, artist, and duration. This means we need to store these values as instance variables within the object. In Ruby, an instance variable is simply a name preceded by an ``at'' sign (``@''). In our example, the parameter `name` is assigned to the instance variable `@name`, `artist` is assigned to `@artist`, and `duration` (the length of the song in seconds) is assigned to `@duration`.

Let's test our spiffy new class.

`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.inspect` | » | `"#<Song:0x401b299c @artist=\"Fleck\", @name=\"Bicylops\", @duration=260>"`

Well, it seems to work. By default, the `inspect` message, which can be sent to any object, dumps out the object's id and instance variables. It looks as though we have them set up correctly.

Our experience tells us that during development we'll be printing out the contents of a `Song` object many times, and `inspect`'s default formatting leaves something to be desired. Fortunately, Ruby has a standard message, `to_s`, which it sends to any object it wants to render as a string. Let's try it on our song.

`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.to_s` | » | `"#<Song:0x401b2a14>"`

That wasn't too useful---it just reported the object id. So, let's override `to_s` in our class. As we do this, we should also take a moment to talk about how we're showing the class definitions in this book.

In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.

This is great for our purposes. As we go through this chapter, adding features to our classes, we'll show just the class definitions for the new methods; the old ones will still be there. It saves us having to repeat redundant stuff in each example. Obviously, though, if you were creating this code from scratch, you'd probably just throw all the methods into a single class definition.

Enough detail! Let's get back to adding a `to_s` method to our `Song` class.

`class Song`
`def to_s`
`"Song: #{@name}--#{@artist} (#{@duration})"`
`end`
`end`
`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.to_s` | » | `"Song: Bicylops--Fleck (260)"`

Excellent, we're making progress. However, we've slipped in something subtle. We said that Ruby supports `to_s` for all objects, but we didn't say how. The answer has to do with inheritance, subclassing, and how Ruby determines what method to run when you send a message to an object. This is a subject for a new section, so....

## Inheritance and Messages

Inheritance allows you to create a class that is a refinement or specialization of another class. For example, our jukebox has the concept of songs, which we encapsulate in class `Song`. Then marketing comes along and tells us that we need to provide karaoke support. A karaoke song is just like any other (there's no vocal on it, but that doesn't concern us). However, it also has an associated set of lyrics, along with timing information. When our jukebox plays a karaoke song, the lyrics should flow across the screen on the front of the jukebox in time with the music.

An approach to this problem is to define a new class, `KaraokeSong`, which is just like `Song`, but with a lyric track.

    class KaraokeSong < Song
      def initialize(name, artist, duration, lyrics)
        super(name, artist, duration)
        @lyrics = lyrics
      end
    end

The ```< Song`'' on the class definition line tells Ruby that a `KaraokeSong` is a subclass of `Song`. (Not surprisingly, this means that `Song` is a superclass of `KaraokeSong`. People also talk about parent-child relationships, so `KaraokeSong`'s parent would be `Song`.) For now, don't worry too much about the `initialize` method; we'll talk about that `super` call later.

Let's create a `KaraokeSong` and check that our code worked. (In the final system, the lyrics will be held in an object that includes the text and timing information. To test out our class, though, we'll just use a string. This is another benefit of untyped languages---we don't have to define everything before we start running code.

`aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...")`
`aSong.to_s` | » | `"Song: My Way--Sinatra (225)"`

Well, it ran, but why doesn't the `to_s` method show the lyric?

The answer has to do with the way Ruby determines which method should be called when you send a message to an object. When Ruby compiles the method invocation `aSong.to_s`, it doesn't actually know where to find the method `to_s`. Instead, it defers the decision until the program is run. At that time, it looks at the class of `aSong`. If that class implements a method with the same name as the message, that method is run. Otherwise, Ruby looks for a method in the parent class, and then in the grandparent, and so on up the ancestor chain. If it runs out of ancestors without finding the appropriate method, it takes a special action that normally results in an error being raised.[In fact, you can intercept this error, which allows you to fake out methods at runtime. This is described under `Object#method_missing` on page 355.]

So, back to our example. We sent the message `to_s` to `aSong`, an object of class `KaraokeSong`. Ruby looks in `KaraokeSong` for a method called `to_s`, but doesn't find it. The interpreter then looks in `KaraokeSong`'s parent, class `Song`, and there it finds the `to_s` method that we defined on page 18. That's why it prints out the song details but not the lyrics---class `Song` doesn't know anything about lyrics.

Let's fix this by implementing `KaraokeSong#to_s`. There are a number of ways to do this. Let's start with a bad way. We'll copy the `to_s` method from `Song` and add on the lyric.

`class KaraokeSong`
`# ...`
`def to_s`
`"KS: #{@name}--#{@artist} (#{@duration}) [#{@lyrics}]"`
`end`
`end`
`aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...")`
`aSong.to_s` | » | `"KS: My Way--Sinatra (225) [And now, the...]"`

We're correctly displaying the value of the `@lyrics` instance variable. To do this, the subclass directly accesses the instance variables of its ancestors. So why is this a bad way to implement `to_s`?

The answer has to do with good programming style (and something called decoupling). By poking around in our parent's internal state, we're tying ourselves tightly to its implementation. Say we decided to change `Song` to store the duration in milliseconds. Suddenly, `KaraokeSong` would start reporting ridiculous values. The idea of a karaoke version of ``My Way'' that lasts for 3750 minutes is just too frightening to consider.

We get around this problem by having each class handle its own internal state. When `KaraokeSong#to_s` is called, we'll have it call its parent's `to_s` method to get the song details. It will then append to this the lyric information and return the result. The trick here is the Ruby keyword ```super`''. When you invoke `super` with no arguments, Ruby sends a message to the current object's parent, asking it to invoke a method of the same name as the current method, and passing it the parameters that were passed to the current method. Now we can implement our new and improved `to_s`.

`class KaraokeSong < Song`
`# Format ourselves as a string by appending`
`# our lyrics to our parent's #to_s value.`
`def to_s`
`super + " [#{@lyrics}]"`
`end`
`end`
`aSong = KaraokeSong.new("My Way", "Sinatra", 225, "And now, the...")`
`aSong.to_s` | » | `"Song: My Way--Sinatra (225) [And now, the...]"`

We explicitly told Ruby that `KaraokeSong` was a subclass of `Song`, but we didn't specify a parent class for `Song` itself. If you don't specify a parent when defining a class, Ruby supplies class `Object` as a default. This means that all objects have `Object` as an ancestor, and that `Object`'s instance methods are available to every object in Ruby. Back on page 18 we said that `to_s` is available to all objects. Now we know why; `to_s` is one of more than 35 instance methods in class `Object`. The complete list begins on page 351.

### Inheritance and Mixins

Some object-oriented languages (notably C++) support multiple inheritance, where a class can have more than one immediate parent, inheriting functionality from each. Although powerful, this technique can be dangerous, as the inheritance hierarchy can become ambiguous.

Other languages, such as Java, support single inheritance. Here, a class can have only one immediate parent. Although cleaner (and easier to implement), single inheritance also has drawbacks---in the real world things often inherit attributes from multiple sources (a ball is both a bouncing thing and a spherical thing, for example).

Ruby offers an interesting and powerful compromise, giving you the simplicity of single inheritance and the power of multiple inheritance. A Ruby class can have only one direct parent, and so Ruby is a single-inheritance language. However, Ruby classes can include the functionality of any number of mixins (a mixin is like a partial class definition). This provides a controlled multiple-inheritance-like capability with none of the drawbacks. We'll explore mixins more beginning on page 98.

So far in this chapter we've been looking at classes and their methods. Now it's time to move on to the objects, such as the instances of class `Song`.

## Objects and Attributes

The `Song` objects we've created so far have an internal state (such as the song title and artist). That state is private to those objects---no other object can access an object's instance variables. In general, this is a Good Thing. It means that the object is solely responsible for maintaining its own consistency.

However, an object that is totally secretive is pretty useless---you can create it, but then you can't do anything with it. You'll normally define methods that let you access and manipulate the state of an object, allowing the outside world to interact with the object. These externally visible facets of an object are called its attributes.

For our `Song` objects, the first thing we may need is the ability to find out the title and artist (so we can display them while the song is playing) and the duration (so we can display some kind of progress bar).

`class Song`
`def name`
`@name`
`end`
`def artist`
`@artist`
`end`
`def duration`
`@duration`
`end`
`end`
`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.artist` | » | `"Fleck"`
`aSong.name` | » | `"Bicylops"`
`aSong.duration` | » | `260`

Here we've defined three accessor methods to return the values of the three instance attributes. Because this is such a common idiom, Ruby provides a convenient shortcut: `attr_reader` creates these accessor methods for you.

`class Song`
`attr_reader :name, :artist, :duration`
`end`
`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.artist` | » | `"Fleck"`
`aSong.name` | » | `"Bicylops"`
`aSong.duration` | » | `260`

This example has introduced something new. The construct `:artist` is an expression that returns a `Symbol` object corresponding to `artist`. You can think of `:artist` as meaning the name of the variable `artist`, while plain `artist` is the value of the variable. In this example, we named the accessor methods `name`, `artist`, and `duration`. The corresponding instance variables, `@name`, `@artist`, and `@duration`, will be created automatically. These accessor methods are identical to the ones we wrote by hand earlier.

### Writable Attributes

Sometimes you need to be able to set an attribute from outside the object. For example, let's assume that the duration that is initially associated with a song is an estimate (perhaps gathered from information on a CD or in the MP3 data). The first time we play the song, we get to find out how long it actually is, and we store this new value back in the `Song` object.

In languages such as C++ and Java, you'd do this with setter functions.

    class JavaSong {                     // Java code
      private Duration myDuration;
      public void setDuration(Duration newDuration) {
        myDuration = newDuration;
      }
    }
    s = new Song(....)
    s.setDuration(length)

In Ruby, the attributes of an object can be accessed as if they were any other variable. We've seen this above with phrases such as `aSong.name`. So, it seems natural to be able to assign to these variables when you want to set the value of an attribute. In keeping with the Principle of Least Surprise, that's just what you do in Ruby.

`class Song`
`def duration=(newDuration)`
`@duration = newDuration`
`end`
`end`
`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.duration` | » | `260`
`aSong.duration = 257 # set attribute with updated value`
`aSong.duration` | » | `257`

The assignment ```aSong.duration = 257`'' invokes the method `duration=` in the `aSong` object, passing it `257` as an argument. In fact, defining a method name ending in an equals sign makes that name eligible to appear on the left-hand side of an assignment.

Again, Ruby provides a shortcut for creating these simple attribute setting methods.

    class Song
      attr_writer :duration
    end
    aSong = Song.new("Bicylops", "Fleck", 260)
    aSong.duration = 257

### Virtual Attributes

These attribute accessing methods do not have to be just simple wrappers around an object's instance variables. For example, you might want to access the duration in minutes and fractions of a minute, rather than in seconds as we've been doing.

`class Song`
`def durationInMinutes`
`@duration/60.0 # force floating point`
`end`
`def durationInMinutes=(value)`
`@duration = (value*60).to_i`
`end`
`end`
`aSong = Song.new("Bicylops", "Fleck", 260)`
`aSong.durationInMinutes` | » | `4.333333333`
`aSong.durationInMinutes = 4.2`
`aSong.duration` | » | `252`

Here we've used attribute methods to create a virtual instance variable. To the outside world, `durationInMinutes` seems to be an attribute like any other. Internally, though, there is no corresponding instance variable.

This is more than a curiosity. In his landmark book Object-Oriented Software Construction , Bertrand Meyer calls this the Uniform Access Principle. By hiding the difference between instance variables and calculated values, you are shielding the rest of the world from the implementation of your class. You're free to change how things work in the future without impacting the millions of lines of code that use your class. This is a big win.

## Class Variables and Class Methods

So far, all the classes we've created have contained instance variables and instance methods: variables that are associated with a particular instance of the class, and methods that work on those variables. Sometimes classes themselves need to have their own states. This is where class variables come in.

### Class Variables

A class variable is shared among all objects of a class, and it is also accessible to the class methods that we'll describe later. There is only one copy of a particular class variable for a given class. Class variable names start with two ``at'' signs, such as ```@@count`''. Unlike global and instance variables, class variables must be initialized before they are used. Often this initialization is just a simple assignment in the body of the class definition.

For example, our jukebox may want to record how many times each particular song has been played. This count would probably be an instance variable of the `Song` object. When a song is played, the value in the instance is incremented. But say we also want to know how many songs have been played in total. We could do this by searching for all the `Song` objects and adding up their counts, or we could risk excommunication from the Church of Good Design and use a global variable. Instead, we'll use a class variable.

    class Song
      @@plays = 0
      def initialize(name, artist, duration)
        @name     = name
        @artist   = artist
        @duration = duration
        @plays    = 0
      end
      def play
        @plays += 1
        @@plays += 1
        "This  song: #@plays plays. Total #@@plays plays."
      end
    end

For debugging purposes, we've arranged for `Song#play` to return a string containing the number of times this song has been played, along with the total number of plays for all songs. We can test this easily.

`s1 = Song.new("Song1", "Artist1", 234) # test songs..`
`s2 = Song.new("Song2", "Artist2", 345)`
`s1.play` | » | `"This song: 1 plays. Total 1 plays."`
`s2.play` | » | `"This song: 1 plays. Total 2 plays."`
`s1.play` | » | `"This song: 2 plays. Total 3 plays."`
`s1.play` | » | `"This song: 3 plays. Total 4 plays."`

Class variables are private to a class and its instances. If you want to make them accessible to the outside world, you'll need to write an accessor method. This method could be either an instance method or, leading us neatly to the next section, a class method.

### Class Methods

Sometimes a class needs to provide methods that work without being tied to any particular object.

We've already come across one such method. The `new` method creates a new `Song` object but is not itself associated with a particular song.

    aSong = Song.new(....)

You'll find class methods sprinkled throughout the Ruby libraries. For example, objects of class `File` represent open files in the underlying file system. However, class `File` also provides several class methods for manipulating files that aren't open and therefore don't have a `File` object. If you want to delete a file, you call the class method `File.delete` , passing in the name.

    File.delete("doomedFile")

Class methods are distinguished from instance methods by their definition. Class methods are defined by placing the class name and a period in front of the method name.

    class Example

      def instMeth              # instance method
      end

      def Example.classMeth     # class method
      end

    end

Jukeboxes charge money for each song played, not by the minute. That makes short songs more profitable than long ones. We may want to prevent songs that take too long from being available on the SongList. We could define a class method in `SongList` that checked to see if a particular song exceeded the limit. We'll set this limit using a class constant, which is simply a constant (remember constants? they start with an uppercase letter) that is initialized in the class body.

`class SongList`
`MaxTime = 5*60 # 5 minutes`
``
`def SongList.isTooLong(aSong)`
`return aSong.duration > MaxTime`
`end`
`end`
`song1 = Song.new("Bicylops", "Fleck", 260)`
`SongList.isTooLong(song1)` | » | `false`
`song2 = Song.new("The Calling", "Santana", 468)`
`SongList.isTooLong(song2)` | » | `true`

### Singletons and Other Constructors

Sometimes you want to override the default way in which Ruby creates objects. As an example, let's look at our jukebox. Because we'll have many jukeboxes, spread all over the country, we want to make maintenance as easy as possible. Part of the requirement is to log everything that happens to a jukebox: the songs that are played, the money received, the strange fluids poured into it, and so on. Because we want to reserve the network bandwidth for music, we'll store these logfiles locally. This means we'll need a class that handles logging. However, we want only one logging object per jukebox, and we want that object to be shared among all the other objects that use it.

Enter the Singleton pattern, documented in Design Patterns . We'll arrange things so that the only way to create a logging object is to call `Logger.create`, and we'll ensure that only one logging object is ever created.

    class Logger
      private_class_method :new
      @@logger = nil
      def Logger.create
        @@logger = new unless @@logger
        @@logger
      end
    end

By making `Logger`'s method `new` private, we prevent anyone from creating a logging object using the conventional constructor. Instead, we provide a class method, `Logger.create`. This uses the class variable `@@logger` to keep a reference to a single instance of the logger, returning that instance every time it is called.[The implementation of singletons that we present here is not thread-safe; if multiple threads were running, it would be possible to create multiple logger objects. Rather than add thread safety ourselves, however, we'd probably use the `Singleton` mixin supplied with Ruby, which is documented on page 468.] We can check this by looking at the object identifiers the method returns.

`Logger.create.id` | » | `537762894`
`Logger.create.id` | » | `537762894`

Using class methods as pseudo-constructors can also make life easier for users of your class. As a trivial example, let's look at a class `Shape` that represents a regular polygon. Instances of `Shape` are created by giving the constructor the required number of sides and the total perimeter.

    class Shape
      def initialize(numSides, perimeter)
        # ...
      end
    end

However, a couple of years later, this class is used in a different application, where the programmers are used to creating shapes by name, and by specifying the length of the side, not the perimeter. Simply add some class methods to `Shape`.

    class Shape
      def Shape.triangle(sideLength)
        Shape.new(3, sideLength*3)
      end
      def Shape.square(sideLength)
        Shape.new(4, sideLength*4)
      end
    end

There are many interesting and powerful uses of class methods, but exploring them won't get our jukebox finished any sooner, so let's move on.

## Access Control

When designing a class interface, it's important to consider just how much access to your class you'll be exposing to the outside world. Allow too much access into your class, and you risk increasing the coupling in your application---users of your class will be tempted to rely on details of your class's implementation, rather than on its logical interface. The good news is that the only way to change an object's state in Ruby is by calling one of its methods. Control access to the methods and you've controlled access to the object. A good rule of thumb is never to expose methods that could leave an object in an invalid state. Ruby gives us three levels of protection.

- Public methods can be called by anyone---there is no access control. Methods are public by default (except for `initialize`, which is always private).
- Protected methods can be invoked only by objects of the defining class and its subclasses. Access is kept within the family.
- Private methods cannot be called with an explicit receiver. Because you cannot specify an object when using them, private methods can be called only in the defining class and by direct descendents within that same object.

The difference between ``protected'' and ``private'' is fairly subtle, and is different in Ruby than in most common OO languages. If a method is protected, it may be called by any instance of the defining class or its subclasses. If a method is private, it may be called only within the context of the calling object---it is never possible to access another object's private methods directly, even if the object is of the same class as the caller.

Ruby differs from other OO languages in another important way. Access control is determined dynamically, as the program runs, not statically. You will get an access violation only when the code attempts to execute the restricted method.

### Specifying Access Control

You specify access levels to methods within class or module definitions using one or more of the three functions `public`, `protected`, and `private`. Each function can be used in two different ways.

If used with no arguments, the three functions set the default access control of subsequently defined methods. This is probably familiar behavior if you're a C++ or Java programmer, where you'd use keywords such as `public` to achieve the same effect.

    class MyClass

          def method1    # default is 'public'
            #...
          end

      protected          # subsequent methods will be 'protected'

          def method2    # will be 'protected'
            #...
          end

      private            # subsequent methods will be 'private'

          def method3    # will be 'private'
            #...
          end

      public             # subsequent methods will be 'public'

          def method4    # and this will be 'public'
            #...
          end
    end

Alternatively, you can set access levels of named methods by listing them as arguments to the access control functions.

    class MyClass

      def method1
      end

      # ... and so on

      public    :method1, :method4
      protected :method2
      private   :method3
    end

A class's `initialize` method is automatically declared to be private.

It's time for some examples. Perhaps we're modeling an accounting system where every debit has a corresponding credit. Because we want to ensure that no one can break this rule, we'll make the methods that do the debits and credits private, and we'll define our external interface in terms of transactions.

    class Accounts

      private

        def debit(account, amount)
          account.balance -= amount
        end
        def credit(account, amount)
          account.balance += amount
        end

      public

        #...
        def transferToSavings(amount)
          debit(@checking, amount)
          credit(@savings, amount)
        end
        #...
    end

Protected access is used when objects need to access the internal state of other objects of the same class. For example, we may want to allow the individual `Account` objects to compare their raw balances, but may want to hide those balances from the rest of the world (perhaps because we present them in a different form).

    class Account
      attr_reader :balance       # accessor method 'balance'

      protected :balance         # and make it protected

      def greaterBalanceThan(other)
        return @balance > other.balance
      end
    end

Because the attribute `balance` is protected, it's available only within `Account` objects.

## Variables

Now that we've gone to the trouble to create all these objects, let's make sure we don't lose them. Variables are used to keep track of objects; each variable holds a reference to an object.

Figure not available...

Let's confirm this with some code.

`person = "Tim"`
`person.id` | » | `537767064`
`person.type` | » | `String`
`person` | » | `"Tim"`

On the first line, Ruby creates a new `String` object with the value ``Tim.'' A reference to this object is placed in the local variable `person`. A quick check shows that the variable has indeed taken on the personality of a string, with an object id, a type, and a value.

So, is a variable an object?

In Ruby, the answer is ``no.'' A variable is simply a reference to an object. Objects float around in a big pool somewhere (the heap, most of the time) and are pointed to by variables.

Let's make the example slightly more complicated.

`person1 = "Tim"`
`person2 = person1`
``
`person1[0] = 'J'`
``
`person1` | » | `"Jim"`
`person2` | » | `"Jim"`

What happened here? We changed the first character of `person1`, but both `person1` and `person2` changed from ``Tim'' to ``Jim.''

It all comes back to the fact that variables hold references to objects, not the objects themselves. The assignment of `person1` to `person2` doesn't create any new objects; it simply copies `person1`'s object reference to `person2`, so that both `person1` and `person2` refer to the same object. We show this in Figure 3.1 on page 31.

Assignment aliases objects, potentially giving you multiple variables that reference the same object. But can't this cause problems in your code? It can, but not as often as you'd think (objects in Java, for example, work exactly the same way). For instance, in the example in Figure 3.1, you could avoid aliasing by using the `dup` method of `String`, which creates a new `String` object with identical contents.

`person1 = "Tim"`
`person2 = person1.dup`
`person1[0] = "J"`
`person1` | » | `"Jim"`
`person2` | » | `"Tim"`

You can also prevent anyone from changing a particular object by freezing it (we talk more about freezing objects on page 251). Attempt to alter a frozen object, and Ruby will raise a `TypeError` exception.

    person1 = "Tim"
    person2 = person1
    person1.freeze       # prevent modifications to the object
    person2[0] = "J"

produces:

    prog.rb:4:in `=': can't modify frozen string (TypeError)
    	from prog.rb:4

Previous < | Contents ^ | Next >

Extracted from the book "Programming Ruby - The Pragmatic Programmer's Guide"
Copyright © 2000 Addison Wesley Longman, Inc. Released under the terms of the Open Publication License V1.0.
This reference is available for download.