Using Many Objects at Once

Posted by Berin Loritsch Wed, 06 Aug 2008 11:53:00 GMT

Last article was meant to introduce you to the terminology that is common to object oriented languages. You should have a clear idea of what an Object is and what a Method is. Today, we are going to learn about how to use more than one object at a time. We’ll start with simple variables, which are simply names for objects you are using so you can get to them again. Then we’ll talk about some special objects called containers, whose sole purpose is to organize a group of objects for you.

A container is an object that holds a bunch of other objects

Variables

So there’s a little more terminology here. We can assign objects to individual variables fairly easily just by giving a name, using the equals sign, and the value. For example:

my_variable = 12345

As long as the first character of the variable name starts with a letter or an underscore “” character, the rest of the characters can be letters, numbers, and underscores. Almost all languages have this requirement, so that the computer doesn’t get confused between what is supposed to be a number and what is supposed to be a variable. Just a little helpful advice from someone with experience here, use variable names that make sense. It is better to type a few extra keys than wonder whether _cntr meant counter or center later on. It’s also better to use names that reflect the variable’s purpose rather than what it is made of.

array = ['cero', 'uno', 'dos', 'tres']
ones_column = ['cero', 'uno', 'dos', 'tres']

The variable named ‘array’ is kind of silly. It describes what kind of object is assigned to the variable rather than what we are using the variable for. The variable named ‘ones_column’ describes the purpose for the variable better. We are using an array of names to write out the ones column of a number.

Variables let us hold on to objects with a user friendly name so we can use them later

Arrays

Since we already introduced how to create an array above, let’s talk about how they are used. Arrays hold a bunch of related values together so that we can use them in interesting ways. Using the ‘ones_column’ example above, we can use any single digit number to get the name of that number.

Arrays are lists of information

puts ones_column[2]

# prints 'dos'

Remember in the last lesson, when we had a number do something using the times method? The number passed back to our code started at zero. The number inside the square brackets is an index number that starts at zero. So the first element in the array is always 0, not 1. That’s why we started the array with ‘cero’ (Spanish for zero) instead of ‘uno’ (Spanish for one).

An Array is a Collection, so like all collections it has an each method. The each method works just like the times method on the number objects. The method will pass back the elements (the objects) of the array one at a time in order. So, if we wanted to count in Spanish, we would use our ones_column array like this:

ones_column.each do |number|
  puts number
end

Hash

A Hash allows you to map one object as a key and another object as the value. Other languages will call the Hash a Map or a Dictionary, essentially letting you look up one object (a definition) using another object (the word to look up). Think of the word key in the terms of a map key. A symbol represents a concept, so to speak.

Hash lets you associate key objects with value objects

In Ruby, Hashes are created using the curly braces, and the key/value pairs are marked with the phrase: key => value . They can be quite handy when you have a lot of information to pass from one place to the next. One variable would take all the name/value pairs. If it helps, think of it as a collection of variables. It is most common to see string names be the key, but in Ruby we also have something called a symbol. Strings are surrounded by quotes, and they can change. Symbols have a colon in front and they never change.

my_map = {'string' => 'surrounded by quotes',
          :symbol => 'starts with colon',
          :string => 'not the same as a string'}

puts my_map['string'] # shows 'surrounded by quotes'
puts my_map[:symbol]  # shows 'starts with colon'
puts my_map[:string]  # shows 'not the same as a string'
puts my_map[:string.to_s] # shows 'surrounded by quotes'

In the above code, we set up a map of keys to string values. Just so you know, the objects don’t have to be the same type. In fact you’ll see that we used one string and two symbols for keys. You’ll also see that the Hash object treats them differently. The last lookup call might cause a little confusion, so look at the method being called on the symbol. The to_s method is on every Ruby object, and it is a convenient way to get a string out of the object. For a symbol, the to_s returns the name of the symbol (everything except for the colon). Because that happens to be the same name as a string key that is already in the map, it returns the value that belongs to the string.

This brings up a very important point, particularly for newbies. Save yourself a lot of headaches, and only use keys of the same type until you know exactly what you are doing. If you ever use many types of objects for different keys make sure you document your code with your comments. You don’t want to run the chance of spending hours tracking down a bug only to find it is the same thing I showed here. Talk about your ‘Doh!’ moments.

Strings

Ok, the Array and Map are good enough to get you going—there are more collection types and more things you can do with these collections, but strings are pretty important in programming. The string is your best tool for communicating with the user. On web forms, your values are all strings, and when you add content onto a page, they are strings. There are three ways of working with strings in Ruby, depending on how much power you need. We will introduce them from the simplest to the most complex.

Strings hold text

simple_string = 'single quotes and no processing'

The above string is rather simple. The single quotes mean to take the text AS IS, no escaped characters, no single quotes, and no formatting. You’d be surprised by how much you can use this simple declaration. If we ever needed to stick two strings together, we can use the plus sign (’+’).

hello = 'Hello'
world = 'World'

puts hello + ' ' + world

#shows 'Hello World'

Things can get messy when you have to show information your program has back to the user. The ’+’ concatenation only works for strings, so each object that is not a string needs to call the to_s method to be concatenated. Oh, and then you still have the problem of formatting the text to be pretty. There is a more powerful way to declare and use strings, and that is to use double quotes:

number = 4

puts "Number:\t#{number}" 

In the string we sent directly to the puts method, we see a bunch of stuff that might look confusing at first. The first funny looking characters would be the ”\t”. The backslash (’\’) is an escape character, so you can access more special characters with it. You can embed double quotes by adding a backslash in front, or in this case you can embed a tab character. Essentially, we told the string to embed some white space. The next set of funny looking characters would be ”#{number}”, but when you realize that the number inside the curly braces is the same name as the variable we defined before, it suddenly becomes a little less confusing. Basically anything between the ’#{’ and ‘}’ will be treated like regular ruby. You can even do math in there if you really wanted. It’s best to keep it simple and only use it to display the value of variables in your string.

That’s all well and good, but what if I have a lot of text, I only need to embed a little bit of Ruby variables, and I want to do all the spacing and carriage returns myself? There is a way to define a big string by providing your own “terminator”. The terminator is just so that Ruby can know when the string is done and it can go back to normal Ruby processing.

really_big = <<-END
This string will keep going and going
on and on until I use the terminator
to make it end.
END

puts really_big

You can embed variables just like before using the ’#{}’ construct, but there really isn’t a whole lot of need for escape characters and such. When you have a big message you want to give to the user, this is usually the best way to get it done. The important thing is that you choose the terminator so it will never be text in your block. The characters ‘<<-’ basically tell ruby to keep adding lines to the string until we reach X where X is the terminator. In my example, I chose the word END in all capital letters, but you could just as well use TERMINAR or BATTLE_FLAG or any other gibberish you want. The string will start on the following line and continue until it hits the terminator you set up. Just make sure it is clear what you are doing so that when you come back to the code later you aren’t thinking What in the world did I do?

Comments

Leave a response

Comments