Advertisement
Ruby

Ruby for Newbies: Working with Classes

by

Ruby is a one of the most popular languages used on the web. We’ve recently started a new screencast series here on Nettuts+ that will introduce you to Ruby, as well as the great frameworks and tools that go along with Ruby development. In this chapter, we'll take a look at creating our own Ruby classes.


Catch Up


View Screencast

Press the HD button for a clearer picture.

Modifying a Blank Object

In chapter two, we learned how to add methods to an already-existing object. If we want to start with a blank object that we can then augment with methods and properties, we can just create an instance of the Object class.

o = Object.new
def o.my_method
  1 + 1
end
o.my_method # => 2

What about properties? Well, Ruby has instance variables (variables that each instance of an object gets); an instance variable starts with an ‘at’ sign (@). You can get and set these instance variables by creating functions especially for that purpose.

def o.set_name ( name )
  @name = name
end

def o.get_name
  @name
end

o.set_name "Andrew"
o.get_name # => Andrew

You should note that the variable @name doesn’t need to be initialized anywhere. Ruby takes care of keeping that organized for you. Now, we can set and get the instance variables @name. However, isn’t it rather ugly to use set_name and get_name for properties? Doing something like o.name = "Andrew" to write and o.name to read would be so much more natural. We’ll see how to do this in a minute; but for now, let’s start creating a class of our own.


Creating a Class

It’s pretty simple to create a class. Just use the following syntax. In this lesson, we’ll be creating a pretty useless Person class:

class Person

end

Again, super-simple. Let’s start filling it in.


Creating Properties

We’ve seen how to create properties: they’re just method wrappers for instance variables. However, we want them to act more like the way you would expect properties to act. It’s easy for the get method:

def name
  @name
end

Since we’re inside the class, we don’t have to give the name of an object in the method signature; just the name of the method will do. When we create an instance of the Person class—say, p1—we’ll be able to call this in the usual way—p1.name.

But how can we improve the look of setting the @name variable?

Ruby gives us an incredible bit of sugar to make this really cool. Check this out:

def name= name
  @name = name
end

Okay, so what? This way, we’re writing p1.name=("joe") or at least p1.name="joe", because parenthesis aren’t required. Is that much better? Well, here’s the cool part: you can put in the spaces and Ruby won’t skip a beat:

p1.name = "joe"

Now, we can write and read our instance variables the way you would expect properties to be read.

But it gets even better. Setting properties via methods like this gives you the opportunity to do something with the value that the user of your class passes in—something more than just assign it to an instance variable, if that's appropriate for your class. However, there’s a good chance that most of the time you’ll do just as we have here: simply set or get the instance variables. In that case, Ruby makes it even easier. Just add this at the top of your class:

attr_accessor :name, :age, :your_properties_here

Pass attr_accessor the names of your properties as symbols. This creates the var and var= methods for you. Then, you’ll be able to use the @ versions wherever you need to in your code.

If you want read-only or write-only properties, you can use attr_reader or attr_writer, respectively. Of course, if you use, say, attr_writer, you can then create a custom reader method if needed.


Creating Instance Method

We’ve seen how to create instance methods; don’t forget you can use those property values if you need to:

def greet
  "#{@name} says, 'Hello there!'"
end

Creating a Constructor

Often, you’ll want to perform some set-up code when an instance of a class is created. This is done in a constructor function. In Ruby, the constructor function is named initialize. Pop this near the top of our Person class:

def initialize (name, age, job = 'unemployed')
  @name = name
  @age = age
  @job = job
end

As you can see, initialize takes three parameters. The third one, job, is optional, because we’ve given it a default value. Of course, this works for any function, not just a constructor function. Now, when we want to create an instance of person, we have to do the following:

joe  = Person.new("Joe", 35, "plumber")
jill = Person.new "Jill", 14

Creating Private Methods

Private methods are functions that can only be called by other functions within the class; they aren’t exposed to the outside world. The usual way to create private methods is this: under all your public code (the instance and class methods), add the keyword private. Any functions that follow this keyword are private.

  # instance and class methods above
  private

  def get_real_weight
    @weight
  end
end # of the class

If you try to call this method on an instance of Person, it won’t work.


Creating Class Methods and Variables

Class methods and properties are functions and variables that aren’t accessible from instances of a class, but from the class itself. For example, let’s create a class method that returns the number of Person instances we have created.

First, we have to create a class variable that will hold the number of Person instances we have created. Class variables are prefixed with two at-signs. So, add this to your class, preferably under the attr_* lines:

@@count = 0

Now, whenever we make a new Person, we want to increment this variable. What’s run every time we make a Person? initialize, of course; so update it accordingly. Now it looks like this:

def initialize (name, age, job = 'unemployed')
  @name = name
  @age = age
  @job = job

  @@count += 1
end

Then of course we have to create the class method:

def self.count
  @@count
end

Now, give this a try:

joe  = Person.new("Joe", 35, "plumber")
jill = Person.new("Jill", 13)
bob  = Person.new "Bob", 70

Person.count # => 3

Note - Ruby doesn't really have class methods (or static methods, as some languages call them). There's actually a pretty cool bit of "magic" going on under the surface that makes these look like class methods. We'll get into that—usually called metaprogramming—in a future chapter.

Conclusion

That’s it for today; if you have any questions, let me know in the comments. Next time, we’ll explore many common methods on the built-in Ruby classes.

PS - I’ve been playing with the sound settings on my microphone. Is the volume in this screncast loud enough, or should it be higher?

Related Posts
  • Code
    Android SDK
    Create a Music Player on Android: Song Playback0d63m preview image@2x
    In this series, we are creating a music player on Android using the MediaPlayer and MediaController classes. In the first part, we created the app and prepared the user interface for playback. We presented the list of songs on the user device and specified a method to execute when the user makes a selection. In this part of the series, we will implement a Service class to execute music playback continuously, even when the user is not directly interacting with the application.Read More…
  • Code
    Web Development
    Testing Your Ruby Code With Guard, RSpec & Pry: Part 2Ruby wideretina preview
    Continue learning test-driven development in Ruby with Guard, RSpec and Pry.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Categories and Extensions0e5ds8 preview image@2x
    Categories are an Objective-C language feature that let you add new methods to an existing class, much like C# extensions. However, do not confuse C# extensions with Objective-C extensions. Objective-C's extensions are a special case of categories that let you define methods that must be declared in the main implementation block.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Methods0e5ds8 preview image@2x
    In this chapter, we'll explore Objective-C methods in much more detail than we have in previous chapters. This includes an in-depth discussion of instance methods, class methods, important built-in methods, inheritance, naming conventions, and common design patterns.Read More…
  • Code
    iOS SDK
    Objective-C Succinctly: Properties0e5ds8 preview image@2x
    Now that we've explored what data types are available, we can talk about actually using them in a productive manner. We learned how to declare properties in Hello, Objective-C, but this chapter dives deeper into the nuances behind public properties and instance variables. First, we'll take a quick look at the basic syntax of properties and instance variables, and then we'll discuss how to use behavior attributes to modify accessor methods.Read More…
  • Code
    PHP
    PHP 101Code
    There's no denying that ours is an incredibly difficult industry. Ever considered learning a second language? Well, how about five? That's what will be required of you, if you intend to become a modern web developer. Considering this, if you're not careful, very quickly, you may find yourself overwhelmed, as you stare blindly at countless confusing blog articles, or techical books.Read More…