Back to Home

Classes and Its Classy Methods

Date: Jan 22, 2015


Class. Ruby's First-Class Object

Classes in ruby are first-class objects. We've used classes all alone. String, Integers, Floats, Arrays and Hashes are all the "Class" in ruby. Thus when we create them, we says

arr = Array.new hash = Hash.new class Person puts "I am a person" end

So when do you want to make a class? Let's just say you have many friends and want to make an old fashioned addressbook with their name, telephone number, e-mail address and address (we we can send a christmas card). So what you need to do is:

name: Sarah Kwak phone_num: 324-2987 e-mail: awesomesarah@sarah.kwak address: Awesome city, CA, 94033

In program, we can make individual person and fill up infomation. Easy. But.. what about you have 100 friends? Instead of typing all the information, we can make the class "ContactList" and put only values so we don't have to duplicate same elements 100 times.

class ContactList def contact_info(name, tel_num, e_mail, address) p @name = name p @tel_num = tel_num p @e_mail = e_mail p @address = address end end sarah = ContactList.new sarah.contact_info("sarah", "324-2987", "awesomesarah@sarah.kwak", "Awesome city, CA, 94033") #So we can just build each friend's information using ContactList class.

When a new class is created, an object of type Class is initialized and assigned to a global constance in this case 'Person'.

sarah = Person.new sarah # => "I am a person"

When Person.new is called to create a new object, the 'new' method in class is run.

Scope of Variables

$Global and CONSTANT Variable

Global and Constant variables are similar. Both have wide global scope. The difference is that constant will throw a warning if you try to change the value while the program is running

@@Class and @Instance Varialbe

Class veriable means that the variable exist over all instances of a class. Class variable is started with @@

class Animal def initialize @@num = 4 end def num_leg @@num end def evolved_leg(num) @@num = num end end dog = Animal.new monkey = Animal.new p dog.num_leg p monkey.num_leg puts "Here comes difference between class and instance variable" p monkey.evolved_leg(2) p monkey.num_leg #=>This will completely change num_leg to 2 p dog.num_leg #This will return 2 as well

Do exactly same exercise with instance variable

class Animal def initialize @num = 4 end def num_leg @num end def evolved_leg(num) @num = num end end dog = Animal.new monkey = Animal.new p dog.num_leg p monkey.num_leg puts "Here comes difference between class and instance variable" p monkey.evolved_leg(2) p monkey.num_leg #=>This will completely change num_leg to 2 p dog.num_leg #This will return 4 because num = 4 only applys to evolved_leg (instance) variable.

To answer the qeustion of which variable to choose, @@class variable will be appropriate when you want to make a variable accessible to ALL INSTANCES of the CLASS.

@instance vaiable will be appripriate when you want to make a variable accessible to ALL METHODS in the CLASS

Instance Variables are just an object's variable. The difference of instance and local variables are - first, instance variables have @ in front of their names. Second, instance variables will be visible to different methods inside of class. Instance variable will be visible to the whole instances of the classes. On the other hand, local variables is visible only to that method or the 'block'.

class Person def fav_num @fav_num = rand(9) end def num_friends friends = rand(5) end def my_info puts @fav_num puts friends end end sarah = Person.new sarah.fav_num sarah.num_friends # => 4 2
#But if I ask to run this code, it will give an Error message sarah = Person.new sarah.my_info practice.rb:13:in `my_info': undefined local variable or method `friends' for # (NameError)
#Because my_info can't get access to local variable 'friends', the code will not run and gives error. The problem will be solved, when friends change local to instance variable. friends => @friends class Person def fav_num @fav_num = rand(9) end def num_friends @friends = rand(5) end def my_info puts @fav_num puts @friends end end sarah = Person.new sarah.my_info # => 3 4

Initialize

Initialize will always execute every time we create a new instance of the class. We can take advantage this automatic initialization process to set an object's state at the time of the object's creation.

Inside initialize method, we can pass the valiable and value.

class Person def initialize(name, sex) @name = name @sex = sex end def name @name = name #all these methods are returning is actual variable name itself! end def sex @sex = sex end end

Because initialize method will run whenever Person was instantiate and called, name and sex variable will be available through out the class. This is the reason we initialize the instance variable so they can be accessed by any method called within the class

Getter / Setter Methods: attr_reader, attr_writer and attr_accessor

Remember that instance vaiable can be only accessed by object's own methods? This is good. Becuase in that way, we can have absolute control on our methods and variables WITHIN the class. What do I mean by 'control'? Can we change the value of the instance vaiable from outside? This is where we need to use 'getter' method like attr_reader, writer and accessor.

The attr_reader method defines the reader method for you. This is a convenient way to define variables. It is always good idea to wrap instance variables in accessor methods instead of directly referring to variables.

# attr_reader will do this def name @name end # attr_writer will do this def tel_num=(new_num) @tel_num = new_num end # attr_accessor will do both of aboves

This is interesting case. In general, when you ahve attr_accessor, you don't want to create method to change variable. Look at line 22-25, the gettingOld method. This method is trying to change 'age' by 1. You would think that you will just do age += 1 but that will throw an error: undefined method `+' for nil:NilClass (NoMethodError)

Why is that? first, 'age' is a local variable so it is not going to be available outside of gettingOld method. Although don't we have att_accessor? which as both reader and setter? Despite the fact that we can access 'age' without having '@' in other places like amIOld method, we aren't able to change 'age' value. We must change @age.

So what's the difference between Object and Class?

A class is the blueprint from which individual objects are created. In object-oriented terms, we say that your bicycle is an instance of the class of objects known as bicycles.