Sunday, May 16, 2010

On Ruby and learning what programming is

People often ask me to teach them a beginner's lesson on Ruby on Rails. I don't want to say..."well you need to learn how web pages work, then how servers work, then HTML basics, and then maybe some javascript, then maybe you could understand what ruby on rails does." Sure, that path may be good for web designers, but what about people who are just interested in what it is?

So here goes...Lesson ONE: You will need a mac, or patience and googling skills to proceed on a PC.

Open up your terminal application on your mac.

(Command then Space bar to search, then type terminal, and click it to open the app)

This is your command line. You can customize it however you want... like 1990's hacker style with green text on black...um, yeah!


Now type: irb in the terminal. That's it...just those
3 letters. Then hit return/enter.

irb stands for Interactive Ruby, i = interactive, rb = ruby.

Okay, so what you just did is start a ruby interpreter so you can speak ruby to your computer.

I know, I know, you don't speak ruby. Well, it's just like learning Spanish or Greek or whatever. It's another language, and it's easy to get started speaking a little.

How do you know it has started?

The command usually never tells you if something you tell it works. It only tells you if something has errors. But in this case we see that the cursor (prompt) changed to these little double arrow things. >>

(If it didn't, and you see an error message instead, then you don't have ruby on your mac, and you need to google how to get it...sorry.)

So, where were we. we were about to start speaking ruby to our computer.

First, let's type a number and ask the computer how it would classify what we entered.

Type: 1.class then press return.
The computer replies => Fixnum

Any guesses here? Fixnum sounds like English, almost. And so does Class. Well, you're right. Ruby is close to English. Before we figure out what a class is, let's ask the computer how it classifies a few more things we can type.

Go to town. Type whatever you want followed by .class and see how many classes you can figure out from the computer. You can see what I typed on the right. For instance, if you type another integer (1, 2, 3, 4, 5...10, 1000000, 99929292, etc) you get another Fixnum

>> 1.class
=> Fixnum
>> 2.class
=> Fixnum
>> 43.class
=> Fixnum

Maybe you typed in a price (like $1.25 or a decimal like 42.2222), and you got back Float

>> 1.25.class
=> Float
>> 42.2222.class
=> Float

What if you wanted to use .25, like 25 cents, or a quarter of something. You need to start the number with a zero like this.

>> 0.25.class
=> Float

You can't start it with a . because you will confuse the computer.

>> .25.class
SyntaxError: compile error
(irb):10: no . floating literal anymore; put 0 before dot
.25.class
^
(irb):10: syntax error, unexpected '.'
.25.class
^
from (irb):10

Remember, Your mac will tell you when it can't figure something out. In the case of .25, it tells you exactly what to do if you read the error closely enough.

Okay, most everyone probably saw an error after typing a word, followed by .class. Something like this
>> stayce.class
NameError: undefined local variable or method `stayce' for main:Object
from (irb):11
Ruby knows numbers by default. It knows what to do with them too. It's kinda like a boring calculator...until you know what to do with it. By the way if you find calculators exciting you can stop reading and paint the town red. type 1 + 1 -1000.027383 * 3.14 / 42 and you will get your answer. You can even use algebraic parentheses in there so you can divide pie by 42 then add, or whatever order you like. There's some output, but it makes ruby look kinda lame so far, so don't stop with the math refresher course.

>> 1 + 1 -1000.027383 * 3.14 / 42
=> -72.7639519671429
>> 1 + (1 -1000.027383) * (3.14 / 42)
=> -73.689190062381

Let's get back to words for a moment. How do we use names and sentences in the Ruby language if the computer can't classify them? And what is a class anyway? And what exactly is a float, or a fixnum?

Floating Point Number and Fixed Numbers are kinds of numbers, Fixed Numbers are integers like 1, 20, and 2030818383, and floats are numbers with decimals. If you took math in high school, you probably remember hearing about them;) Ruby has different kinds of Classes for numbers because it treats different numbers differently. Each class has some rules and characteristics so Ruby knows how to handle all objects in a certain class. Almost everything in Ruby is an object. Whatever you type that ruby accepts becomes an object and gets classified as some class.

Another kind of Class is a string. "Strings" is how ruby classifies text you give it. To tell Ruby that you want to use a string, you put it in quotes like this:

>> "stayce".class
=> String
>> 'stayce'.class
=> String

You can use single or double quotes to encapsulate your new string. You can even use spaces, so long as your string begins and ends with quotes.

>> "My name is Stayce".class
=> String

Are you bored yet? Wanna learn a little more? First let's do a checkin to make sure I've explained myself. You should be learning that your mac has an interpreter called IRB. You can type commands in the Ruby programming language into it and it will return what you ask it in Ruby. Ruby has built-in classes, and when you give ruby an object it classifies your object into one of these built-in classes and tells you which kind, or else it throws an error. Integers are fixnums, decimals are floats, and text objects are called strings. Ruby uses these classification to know things about the objects in a class. In the same way we know all dogs can have four legs, fur, and bark; Ruby knows all strings can have letters, numbers, punctuation, and should retain capitalization and spacing, where as members of the fixnums or floats classes can be added together or multiplied because they are kinds of numbers.

So, pause for a moment and carve out a neural pathway for the terms Class and Object. Don't stop and google these terms. Make your own definitions based on your learning experience using the terminal. Remember and understand, even if it's a loose understanding that "Objects are members of a Class". Let's go on to lesson 2.

Lesson 2 - Methods

Classes have methods to go with them. That sentence probably means nothing to you so let's examine it in the terminal.

I'm going to make an object of my name, Stayce. Stayce is not a number, right? It's a string, so I need to put it in quotes. Remember when we typed:

>> "Stayce".class
=> String

That checked to see what class "Stayce" is. We asked what class by appending .class, and Ruby said it's a string. This time we know my name is a string, so let's use a string method on it. Strings have lots of methods built into Ruby. They all have names that are close to what they do. Let's try the length string method. This method tells you how many characters are in a string.

>> "Stayce".length
=> 6

My name is 6 characters long. I wonder how many characters are in my full name? What if I type my full name in between the quotes and then call the length method? Will Ruby count the space? Yes, it will. Spaces count as characters in Ruby. There's probably a method to count letters in Ruby, but I don't know it because there are at least a hundred string methods. Luckily you can look them up here: Class: String

Can you use a string method on another class? Remember the number 2 belongs to the fixnum class, and "stayce" belongs to the string class. What happens if you try to use a String Class Method like .length on a FixNum Class object like the number 2?

>> 2.length
NoMethodError: undefined method `length' for 2:Fixnum
from (irb):21

That's an easy error message to decipher right? Undefined method length for 2, a member of the Fixnum class. You probably didn't think that would work. We need to use Fixnum methods on objects from the Fixnum class. Find the length of characters in a number doesn't sound like a common problem, so it's not enabled by default. You could write your own method, or you could choose a Fixnum method to use instead that might do something more interesting. Let's look at a couple of number methods. There's 118 methods to choose from, but most of them involve math so it's kinda boring. Let's try to find a cool one...how about one with a question?

>> 7.even?
=> false

It's probably obvious i think what you are asking here.

>> 13.odd?
=> true

When you have a method that ends in a question, you are looking for something called a boolean response. Boolean means it can have one of only 2 values, usually written in english as true or false.

Let's get back to our silly question of how do you count the characters in a number if the .length method only works on strings? Well, you use a converter method to convert your fixnum to a string, then you can use the string method to count it.

>> 42.to_s.length
=> 2

The .to_s method works on objects in number classes like Fixnum and converts them to strings. Then we can use the .length string method to find out how many characters are in the string "42".

We could also put the number 42 in quotes before we call the string method length, to force the computer to treat 42 like a string instead of a fixnum.

>> "42".length
=> 2

One last thing to do with numbers. Let's change an integer to a float class. What if we have the number 23 but we want to store it as a decimal, like 23.0 so that it can be classified with all the other floats. We can convert it to a float using the fixednum method .to_f which stands for to float.

>> 23.to_f
=> 23.0
>> 23.0.class
=> Float

That's it. Not much to recap here. Find out what kind of class your object is by typing .class. Look up methods you can use on that class. Change the class of an object. Chain methods together and see them operated in order, like you did with this one 42.to_s.length.

Lesson 3 Variables

Remember variables from math class? Finding the value of x? Well, you don't need to find the value of anything right now. We're going to be setting the value of our variables in Ruby. Why would you use a variable? Well, sometimes it's shorter to call something by an acronym. In my silly example, I'll pretend I make a website for the California Dental Hygienists' Association. I don't want to type all that out all the time. I'll make a variable called cdha. I'll make it a string so I can store all the text with the capitals and spacing. To declare a variable, regardless of what type, just type what you want to call it, followed by the equals sign. You don't need quotes around the variable or the = sign. In my case I want to store the string California Dental Hygienists' Association, so I wrap my string in double quotes so Ruby is prepared to take classify my object as a string.

In the IRB prompt in your terminal type in a variable-- make up your own like >> name = "your name"

>> cdha = "California Dental Hygienists' Association"
=> "California Dental Hygienists' Association"

Now you can refer back to your variable with the short form.

>> cdha
=> "California Dental Hygienists' Association"

>> cdha.length
=> 41

>> cdha.class
=> String

You can also do operations on your variables like:

>> name = "Stayce Kavanaugh"
=> "Stayce Kavanaugh"

>> name
=> "Stayce Kavanaugh"

Maybe I want to add the string Hello to my name. I'll remember to include a space after the hello string.

>> "Hello " + name
=> "Hello Stayce Kavanaugh"

Remember name is a variable and not a new string. Ruby already knows what class name is, so you don't need to use quotes on your variable.

>> name.class
=> String

You can make as many variables as you like and store any data in there.