Objects and Classes (brief)

This is going to be a high level post about classes, objects and scope. So in Ruby a class is where you create objects and objects become instances of that class. In makes more sense in terms of an analogy. If you think of a class as a classroom you have student objects that are instances within that classroom.

The students have relationships to one another they might be the same age or be the same height, same gender, but they are all unique. If I created this classroom of students (students class) I would define it in ruby like this;

class Students
end

Always first letter capitalized. To create a new object (or student object) in this class I would call the new method on Students and would store this in a variable.

student1 = Student.new
student2 = Student.new

notice: student1 is something totally different from Student.

Last post I talked about the initialize method, that method defines the parameters that you can pass when calling .new on a class. So you could have default height, gender, age any number of parameters set for a new student or you could define them specifically for that instance of your class.

If you haven’t seen already an important thing to note about classes is inheritance. Some programming languages do this different but in Ruby to inherit the behaviours from another class you just define it at the same time you are defining your class.

class Students variable
instance variable -> @variable
class variable -> @@variable
global variable -> $variable.

So when you are defining the variable it is important to remember to use the correct prefix based on where you want to use it. A class variable has to be initialized when you create them and that variable will then exists for all objects that are crated within that class. For example @@size_of_feet if created in the Students class would be available for each instance or object within the class. Similarly we could define a variable that would only be used in one instance of that class like @favorite_hockey_player just for the boys object in the students class.

Methods

Every time you see

def some_one
...
end

‘some_one’ is a method. Methods let you store a block a code and execute it when you call the method name. You can also use  a method to pass arguments. If I said some_one(name) that would be an argument for the method. I could then say:

def some_one(name)
puts "Hello #{name}"
end

Which would allow me to do this.

some_one("Kyle")
=> Hello Kyle

I can also use a default for the method argument.

def some_one(name = "there")
puts "Hello @{name}"
end

some_one()
Hello there

Those are really simple examples but there is no need to complicate things. A method stores some functionality that you can call later, it becomes more useful when you pass it arguments. In the Ruby documentation they give an example of a greeter method where they create a say_hi and say_bye method in that instance you could call a method depending on whether the user is coming or leaving the site. It’s common to group similar methods into a class, we don’t cover that here but there is a method called ‘initialize’ called inside of classes that is very important. You will see the initialize method a lot so it’s important you know what is happening.

The world initialize in english means to start something so think of it as the method that starts things off. An initialize method will hold methods that will happen automatically every time an instance of a class is created. This just means if we setting methods inside the class they will have the opportunity to use the default values that have been set or whatever the initialize method contains. I will give a quick example here before I finish explaining what initialize does to help try to make it clear.

 
class Greeter 
 def initialize(name = "world") 
  @name = name 
 end 
 def say_hi 
  puts "Hi #{@name}!"
 end 
 def say_bye 
  puts "Bye #{@name}, come back soon"
 end 
end

So what is happening is we are telling the computer that when we call the say_hi or say_bye method there should be parameters of a name passed. If there aren’t any parameters passed we will say world. If name didn’t have a default value it would just be (name) and below it we have created the instance variable @name which = the value of name. So if you did pass a name it could have been stored in that variable. Here’s how it looks in action.

>> class Greeter 
>>  def initialize(name = "world") 
>>   @name = name 
>>  end 
>>  def say_hi 
>>   puts "Hi #{@name}!"
>>  end 
>>  def say_bye 
>>   puts "Bye #{@name}, come back soon"
>>  end 
>> end
=> nil
>> b = Greeter.new()
=> #
>> b.say_hi
Hi world!
=> nil
>> c = Greeter.new("Kyle")
=> #
>> c.say_bye
Bye Kyle, come back soon
=> nil
>> d = Greeter.new("Kyle","John")
ArgumentError: wrong number of arguments (2 for 1)
	from (irb):16:in `initialize'
	from (irb):16:in `new'
	from (irb):16

I’m creating a new instance of the Greeter class. Every time I do that it’s running the initialize method which is allowing me to pass no parameters and still get Hi world! If I call the new method on greeter then pass “Kyle” I can use the variable I stored that parameter in to say Hi Kyle or in this case Bye Kyle, come back soon. Lastly you can see that it won’t accept more parameters than were defined.

There are a couple other things to know about initialize:
- How do we pass the arguments into initialize?… the .new method takes values it has and passes them into initialize.
- Once we start adding arguments to .new it always expects them… unless we set default values.

- If you are working with an object and what to know what methods have been defined on it you can call .instance_methods(false) … if you just called instance methods it would return all of the ones defined by ancestor classes.

Last thing we are going to mention about methods because you will see it so often is attr_accessor methods. There are three attr methods
attr_accessor – creates a getter a setter
attr_reader – creates a getter
attr_writer – creates a setter

The reason you wouldn’t just use accessor for everything is mostly because of performance you don’t need to have a bunch of methods in your program that will never be called.

Getter and setter methods.
above we created an instance variable of @name so that we could read the name we passed in the arguments but if we want to be able to write the name we need to do something that looks like this.

def name =(str) 
 @name = str 
end

That way our name is set to a string.

so by saying

def name 
 @name 
end

We can read the name and the above lets us write the name. Creating these two types of methods happens so often that ruby gave use attr methods to speed up this process. I’m sure you can tell from my description above which one does which.

If I want to create them all I have to do is call them.

attr_accessor :name (does everything I did above) getter and setter both finished and the instance variable is still available for use so I could also make other methods within my class like.

def greeting 
 "Hello #{@name}" 
end

Then I can do a bunch of different things once I call .new on the class. I can set that instance to a variable g, set the name with:
g.name = “Ron” … then call my new greeting method
g.greeting => “Hello Ron”

Hope that helps clarify some things I will probably be back to make changes to these posts but in the meantime check out the Ruby documentation if anything I say doesn’t make sense.

Code Blocks

This will get edited and added upon as everything starts to tie together but for now code blocks are found between either do and end or parentheses {}. It is suggested that you use do/end for multi-line blocks and {} for single line. In general {} has precedence over do/end but we won’t worry about that for now.

A simple example of a block is

>>5.times {puts "Hello"}
Hello
Hello
Hello
Hello
Hello

That is fairly self explanatory. We iterate on the times method by the integer 5 which executes our block 5 times.

Here the instance variable @names is being iterated on by the method each. (Instance variables are represented by one ‘@’ prefixed to the name, class variables have two (ie. @@variable where as our block variables have no prefix) Instance variables have a limited scope to the object that is defined as self, the class variables are obviously available for all of the methods and objects within the class and the block variables  have a limited scope that is only available with their block. 

@names.each do |name|
  puts "Hello #{name}!"
end

if the @names object responds to each it is something you can iterate over .. so we greet each person in turn.Each is a method that accepts a block of code then runs that block for every element in a list, and the parts between do and end are such block.

A block is like an anonymous function or lambda. The variable between pipe characters is the parameter for this block.

In this scenario for every item in the list name is bound to that list element and then the expression puts “Hello @{name}!” is run with that name.

inline that would look like @name.each {|name| puts “Hello @{name}!”}

Some common methods that make use of blocks are find, merge, collect, sort and inject.

FIND – allows us to find objects inside a data set

MERGE (only for hashes) ->

>> h1 = { "a" => 111, "b" => 222}
=> {"b"=>222, "a"=>111}
>> h2 = { "b" => 333, "c" => 444}
=> {"c"=>444, "b"=>333}
>> h1.merge(h2)
=> {"c"=>444, "a"=>111, "b"=>333}

You can see that b was defined twice and ruby automatically takes the last definition.
We can use a block to specify which version of “b” we want.

 
#note that this is an optional block and will only get ran if there is a conflict between #the two keys. Remember the key value system for hashes "b" is the key. 
>> h1.merge(h2) {|key, old, new| old }
=> {"c"=>444, "a"=>111, "b"=>222}

If you want to make the merge permanent add an ‘!’ after the method. (ie. h1.merge!(h2))

COLLECT (or MAP does the same thing) – works best with arrays, hashes and ranges.

 
>> array = [1,2,3,4,5] 
=> [1, 2, 3, 4, 5]
>> array.collect {|i| + 1 } 
=> [1, 1, 1, 1, 1]
>> array.collect {|i| i + 1 }
=> [2, 3, 4, 5, 6]
# you can see the first time we tried to use collect because the variable wasn't called it just entered plus one for each instance.

What is happening here is it’s iterating through our array and passes each value up to the variable i, it then does whatever we tell it to in our code block (in this case add one) then puts that value into a new array.

Things to note when using collect:
- number of items in = number of items out (even though it works with hashes and ranges it always returns an array)
- when using puts… the return value is always nil.

SORT — is a comparison and uses the ‘comparison operator’ <=>
value 1 <=> value 2
returns -1 if one thing is less than the other
0 if they are the same
returns 1 if one thing is greater than the other

so we can use this applied to sorting
-1 moves “left”
0 stays
1 moves “right”

>> array = [3,1,1,5,6,2] 
=> [3, 1, 1, 5, 6, 2]
>> array.sort {|v1,v2| v1 <=> v2}
=> [1, 1, 2, 3, 5, 6]

You can also use sort with strings to do alphabetical sorts and other things like that.

INJECT – “accumulator”
- it is standard to refer to this as memo

With collect we had a transformation iterate through a range but with inject we have it accumulate as it goes along and then store it inside memo. For example:

 
>> (1..10).inject {|memo,n| memo + n } 
=> 55

We declared memo to be the accumulator, ‘n’ variable is where each one of the elements will be yielded up so we can use it in our block. When it starts out memo is going to be equal to 1 because it takes the first value as its initializer.

What is actually happening behind the scenes:

memo = 1
memo = memo + 2
memo = memo + 3
memo = memo + 4 …

Another example:

 
#remember the splay operator turns this into an array
>> array = [*1..10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> product = array.inject(100) {|memo, n| memo * n }
=> 362880000

#to reiterate what ever happens after || is what will be stored in memo for the next iteration

The real power of blocks is shown when dealing with things more complicated than lists. you can handle setup, teardown and errors. The example from below is a snipet from a Greeting class where we are planning to say hi and say bye to certain people depending on the methods they respond to .

# Say bye to everybody
def say_bye
  if @names.nil?
    puts "..."
  elsif @names.respond_to?("join")
    # Join the list elements with commas
    puts "Goodbye #{@names.join(", ")}.  Come back soon!"
  else
    puts "Goodbye #{@names}.  Come back soon!"
  end
end

Here say_bye doesn’t sue each… it checks to see if @names responds to the join method and if so, uses it. Otherwise just prints out the variable as a string. The moethod of not caring about the actual type of variable just relying on what methods it supports is known as “duck typing” (if it walks like a duck and quacks like a duck). The benefit being that if someone comes up with a new kind of list class as long as it implements the join method with the same semantics as other lists everything will work as planned.

But we will come back and cover the more complicated use cases later for now just know what’s happening in the blocks we have made.

Control Structures: If:else, unless, by case & loops

Control structures aren’t as hard as they look. Their main function is to provide action in Ruby. If you look at someone’s code for a web application a lot of it will be made up of these control structures. They are defining all of the scenarios that the user could take for a certain function. So for example if you were to write an online test that had a math problem then a field for the answer your users will clearly not all get the same thing, unless it’s a really easy problem I suppose. But depending on the answer they give, you could return different messages to them. Your program will run through your conditional structure until it finds a scenario that is returned as true and will execute the corresponding block of code. It is common to have a catch all at the end that handles all other cases as well.

For example there are two common ways to test an expression. IF statements or UNLESS statements. Their functions are just like the english language; if statements will execute the code block if the expression is true and unless statements will execute while the code block is false.

IF example where a = 10 (assignment operator)

if a == 5
a = 9
end

– a would print 10 because the if statement was false. I can also write this on one line:

if a == 5: a=9 end  … it’s saying if a was 5 then set it to 9 .. but it’s not, it’s 10.

An example with unless:

a=10
unless a==5
a = 2
end

– here a would be 2 because we’re saying unless it’s 5 exactly any other number would make it 2. If it is 5 then it returns nil .

Where conditional structures really come in handy is with if-elsif-else expressions. Note how elsif is spelt. This expression can handle any number of situations. Lets say your variable a is set to 5. You have a box where someone is trying to guess the value of the number and you have three different responses; your number is too low, your number is too high and you got it right.

Answer:

a=5
if a == 5
print "Hooray, you got it!"
elsif a < 5
print "Sorry, you're too low"
elsif a > 5
prit "Sorry, you're too high"
else
print "Try again"
end

– In this scenario else really has no function because if you entered some other value other than a number it would return an error and our last elsif handles all other possible number solutions but you can see how the else block would handle edge cases of our expression.

An alternative to writing if-elsif-else statement is case expressions. We can do the same example above with a case expression like so:

 case
 when a < 5 then puts "less than"
 when a > 5 then puts "greater than"
 when a == 5 then puts "equal to"
 end
 >> equal to

to save a little bit of time when you get comfortable with what the syntax means you can replace then with “:”.

Last thing we will cover here is loops and iterators which go hand it hand. Just like they sound loops allow you to go through a code block over and over again. Common syntax for loops in ruby are while or until.

For example a really simple example of a while loop.

$i = 0
$num = 5

while $i < $num  do
   puts("Inside the loop i = #$i" )
   $i +=1
end

which prints:

Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4

You could do the same thing with an until loop by saying until $i > $num do …

An extremely common loop to see is .each do. Here I can specify a loop on a range for example:

(0..5).each do |i|
   puts "Value of local variable is #{i}"
end

Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5

One other thing to mention is a few common statements you can run in your loops; break, next, redo & retry. Break will terminate the loop if called inside the block. Next is a good way to skip something inside your loop, it will jump to the next iteration. Redo does exactly what it says, restarts the iteration. Retry also does what it says but will make more sense when we start calling rescue methods on our blocks.

Types of Objects in Ruby Cont..

Last post I just briefly started talking about Arrays but there is a few cool things you can do with them that I didn’t mention. I can call methods on array to edit or find out a number of things about them. For example I can see what’s actually in the array using .inspect …. I can tie everything in the array together using .to_s or .join …. .join is special though because I can join the array with another object if I want. In this case I can say array.join(“, “)  and it will join all the objects in my array with a comma then a space. Some other things I can do is add things to the end of my array using the >> (append) function or .push will do the same thing. The opposite of .push is .pop where I would be pulling the last object out. The important thing to know about arrays is that they are ordered. If the order matters to my list of objects then I will use an array, allowing me to filter and search by the position an object is in.

Alternatively if order doesn’t matter I would use a Hash. Rather than being integer indexed (can search by number) a hash is indexed by object, meaning if you are looking for something inside your hash you couldn’t specify by which place it was in you would have to search by the object name. To keep track of the positions within a hash we use a key, value pair. A key is an object that holds the value which is another object.(ie.  first_name => “John” … first_name is the key and “John” is the value).. In almost all cases we will be looking for something inside a hash based on the key but if for some reason we wanted to find the key based on the value we would use the .index method to do that. One thing that might come in handy that is worth mentioning is to_a (means: to an array) which puts all the key value pairs into their own arrays inside of a bigger array that is your entire hash.

The next object I want to cover is Symbols. Symbols are just a label that is used to identify a piece of data. They are always preceded by a colon, so for example :test is a symbol and so is :this_test. They are good to use when all you’re looking for is a label but to clarify they are not variables. Lastly, they are immutable objects or they don’t change.

A Boolean represents either a true or a false value, it can’t be anything else. A few of the symbols that are common to see with booleans are == which means equal to, it’s evaluating whether something is equal to something else not setting the value. || two pipes is the “or” symbol. You could say 1 <= 5 || 10 >= 50  which would return true. The exclamation mark means not. 10 != 9 .. here 10 obviously does not equal nine. Lastly && is simply and. So if I said 1 >= 5 && 10 >= 50 it would return false.

Next up is a Range. This is really simple, instead of saying [1,2,3,4,5,6,7,8,9,10] in an array we can say 1..10 in a range. There’s a couple important things to know here: the difference between 1..10 and 1…10 is significant. Two periods is an inclusive range and three dots is exclusive. It’s recommended you just always use two so you don’t confuse yourself.

The last type of object is the Constant. Constants are not meant to change, they are constant (stay they same), similar to symbols. Anything that starts with a capital letter is a constant but typically they are in all capitals.

OK that’s it. A really brief overview of the object types in Ruby. Like anything there is way more to know about it but the basics will let us get to the next step from there we can look up methods we can call on an array or whatever we need to in the Ruby documentation.

Gettings Started with Object Types: Variables, Integers, Floats, Strings & Arrays

Like I mentioned earlier everything in Ruby is an object _except_ one thing; a variable. Variables let us reference objects and as soon as they are referencing an object act just like that object. So they have one of two states; undefined or acting like an object. In ruby common practice to keep your variable names readable. They should all be in lowercase and connected with underscores (ie. new_variable).

The way Ruby reads numbers is either Integers or Floats. Integers are literally just whole numbers. One thing to note is that you can use assignment operators like += when using numbers to first carry out the operation then reassign the variable. For example if x = 5 and we said x += 3 … we would get an output of 8 and x would also be set to 8. One other thing to mention is Fignum and Bignum.. you will see come across these in Ruby and they are just subclasses of Integer. They just specify whether Ruby should be using a lot of memory to store the number (Bignum) or not (Fignum).

By definition a String object holds and manipulates a series of bytes that are usually characters. Most commonly they look like this => “Hello” .. ‘Hello’ is the same thing. Double quotes allow you to use escape or special characters inside strings. So for example if I were to say ‘I’m new’ you could see how that would be a problem, rather than “I’m new”. The best way view the single quotation as a literal is using a backslash in front of the character to tell ruby that it is a literal.So you would say “I\’m new”.

Lastly I’ll briefly mention arrays. An array is an ordered integer-indexed collection of objects. Which means you can specify what place objects are within an array and use that positioning to call all kinds of methods and manipulate the array however you want. For example ["a", "b", "c", "d", "e"] is an array. It’s important to note that in this case a is in the 0 position and b would be in the first, it’s zero indexed ordering that’s just how it is so keep that in mind as you go on. I’m going to keep things really simple and go step by step through everything so I’ll end this here. There’s obviously a lot more to know about these object types but I’m just trying to lay it out in terms anyone would understand.

Ruby Overview

I had dived into ruby koans and was working on a blog post about object’s array’s and strings, might throw hashes in there too, when I decided I should do an overview of what everything is first.

Ruby is an Object orientated programming language. In Ruby, as I’ll go over in the next post everything is an object. An Object orientated programming language (the most popular being: java, python, c++, visual basic, .Net and of course Ruby) defines concepts as objects which take attributes and methods to describe what they do. Using Objects, which are actually instances of classes, together you can execute functionality and create computer programs.

Rails on the other hand, you will often hear Ruby on Rails together, is a “full-stack web application framework”. Full stack basically means you can do it all in one place.. other common “Stack’s” are LAMP (linux, apache, mysql, & php, perl or python)  in this case they represent an operation system, a web server, a database and a scripting language. I will get to rails after I have a better understanding of how to use ruby at least to the point where I can look things up and figure out what’s happening.

If you are looking to get started learning as well I wouldn’t even bother downloading IDE’s and rails and text editors yet. I have a bunch downloaded because I thought that was the first step but there are plenty of web based tools and tutorials like Try Ruby or ruby koans where you don’t actually have to download anything to get started. Once you have decided that it is something you are going to pursue do a little bit of research into text editors and IDE’s to see which you would like to use. I have ruby mine and textmate but I think I’m going to switch to coda for a text editor, it’s a little bit more expensive than textmate but I’ll have to weigh my options.

Sadly it actually took me a little bit of time to figure out how to install all the Ruby gems using terminal in mac but you can download them here and if you need help installing the instructions are here.