Matthias Borgeson wrote:
> I am now trying to grasp what a class isand what is is for. I understand
> that there a bunch of different classes, but how does that help me?

In your code you use a lot of objects, right? Like 1 is an Integer object,
"hello" is a String object, /\d+/ is a Regexp object, [] is an Array object, 
2..3 is a Range object (made out of two Integer objects) and so on.
You will have noticed that those objects all have a different set of methods:
You can do (2..3).each or [1,3,5].each, but you can't do 4.each or /la/.each.
You can do "I'm a string".length, but you can't do 3.length.
You can do 5.times, but you can't do "hello".times.
And it makes sense that it works that way, right? Cause what would the length 
of an Integer be? Or what would it mean to execute a block of code "hello" 
times?
As you can see, certain methods only make sense when used with a certain kind 
of object. But how does Ruby know which objects are supposed to have which 
methods? It know because of classes:
Every object is an instance of a class. "hello" is an instance of class 
String, 5 is an instance of class Integer (Fixnum actually, but let's not 
care about the difference at this point), 3..4 is an instance of class Range 
and so on. Those classes describe what properties and methods their instances 
have. "hello" has the methods length, gsub, tr and so on because they are 
defined as methods of String. 2..5 and ["a","b","c"] have the method each 
because in the class Range as well as in the class Array there is a method 
called each. And so on.

But what can you do with classes? Well, you can use those classes by using 
their instances. But you're already doing that. Even when you do 3 + 5 you're 
using two instances of a class (3 and 5 of class Integer) and one method of 
that class (the method +).
So what else can you do with classes? For starters you can extend the existing 
classes. Let's say you have a method that "censors" a string:

def censor(string)
  string.gsub(/./, "x")
end

You can use it like this: censor("hello world"), but now you're thinking that 
it would be much more fun if you could use it like this: "hello world".censor 
cause after all: all the other methods working with strings are used that way 
too. So here's how you'd do that:

class String
  def censor()
    self.gsub(/./, "x")
  end
end

Now you can type "hello".censor and get back "xxxxx" (how very useful, isn't 
it). You will have noticed that where we previously said string.gsub we now 
said self.gsub. Why's that? That's because the parameter string doesn't exist 
anymore. We want to call the method like mystring.censor() without any 
paramether. The method should work with the string that's in front of the dot 
(also called the receiver of the method) and not with any parameter. So how 
do we access the receiver? By using self. Inside a method definition self 
will point to the object that the method has been called on. So when you 
do "hello".censor, self is "hello" and if you do "bla".censor, self is bla. 
Actually we wouldn't have even needed to use self in there: If you call a 
method and you don't specify a receiver (i.e. you write foo() instead of 
self.foo() ), the receiver is assumed to be self. So gsub(...) would be the 
same as self.gsub(...).

So that's how you can extend existing classes. But sometimes that's not 
enough. I mean think about what kind of objects does ruby have? Strings, 
numbers, ranges of numbers, ranges of strings,... BORING! You're a people 
person, you can't be expected to sit in the basement all day and only work 
with numbers and strings. So ruby clearly needs a way to use people in your 
program. So what we do is we create a class called Person that describes what 
properties a person has and what he/she can do (what methods he/she has). So 
that we can then use Person objects (I know you usually shouldn't think of a 
person as an object, but here it's okay) in our code. Here's how to:
First you decide what properties a person should have. For now let's keep it 
small and only let him/her have a name.

class Person
  def initialize(firstname, surname)
    @fname = firstname
    @sname = surname
  end

  def name()
    "#{@fname} #{surname}"
  end

  def firstname()
    @fname
  end

  def surname()
    @sname
  end
end

So how do you use this class? Like this:

my_person = Person.new("John", "Smith")

new is a method that can be used on classes. It creates an instance of this 
class and then calls a method called initialize on it (that's why we defined 
such a method in our class). So now our initialize method gets called with 
the parameters firstname and surname. All it does with those two is store 
them: the value of firstname gets stored in @fname and the value of surname 
in @sname. Variables starting with an @-sign are so called instance 
variables. They're properties of an object. If a method sets an instance 
variable to some value, all methods that get called on the same object can 
now see this value when they access that variable.
Other than initialize there are three other methods: firstname, surname and 
name. firstname and surname are boring. All they do is return the value of 
the instance variable @fname or @sname respectively. name is a bit different. 
It uses @fname and @sname to create the full name and then returns that. Of 
course you can do things far more advanced than this with classes, but this 
should give you something to start with.

HTH,
Sebastian
-- 
Jabber: sepp2k / jabber.org
ICQ: 205544826