Self, Getter and Setter methods and initialize, accessors concepts explained in Ruby
While I was reviewing some concepts in Ruby, I thought it would be nice to make an article about some of main concepts. I will be touching basic concepts of Ruby. However, they are crucial topics.
Self
Self is a keyword in Ruby representing the default object of the current context.
So, in picture 1, we have a class method Drink, this Drink class have a method called show_yourself in line 15. and in picture 2, we have 2 instance of this Drink class. one martini, the other mach.
So, let’s look out our pry to see what show_yourself method gives us. When you look at picture 3, martini.show_yourself gives us <Drink:0x0007…>
The self
keyword refers to the instance, or object, that the #show_yourself
method is being called on. So, when we call #show_yourself
on martini, the method will puts
out to the terminal the Drink
instance that is martini.
I guess we are done with this example. How about when we make a method like in picture 4.
When we type a method with in front of self keyword, we made a class method.
If we type this method on binding.pry. It will gives us Drink class itself.
Getter Method
# this part I took everything from dev.to. They explain concept very well.
A getter method is a method that gets a value of an instance variable.
Without a getter method, you can not retrieve a value of an instance variable outside the class the instance variable is instantiated from.
class Movie
def initialize(name)
@name = name
end
end
obj1 = Movie.new('Forrest Gump')
p obj1.name #=> undefined method `name' for #<Movie:0x007fecd08cb288 @name="Forrest Gump"> (NoMethodError)
As you can see, the value of obj1
(name
) can not be retrieved outside Movie
class. if you try to retrieve a value of an instance variable outside its class without a getter method, Ruby raises No Method Error.
Now, Let’s see how to retrieve the value of obj1
outside Movie
class with a getter method.
All you have to do here is to define a getter method
named name
. Though the name of a getter method can be anything, it is common practice to name a getter method the instance variable’s name.
class Movie
def initialize(name)
@name = name
end
def name
@name
end
end
obj1 = Movie.new('Forrest Gump')
p obj1.name #=> "Forrest Gump"
Setter Method
# this part I took everything from dev.to. They explain concept very well.
A setter is a method that sets a value of an instance variable.
Without a setter method, you can not assign a value to an instance variable outside its class.
if you try to set a value of an instance variable outside its class, Ruby raises No Method Error just like it does when you try to retrieve a value of an instance variable outside its class without a getter method.
class Movie
def initialize(name)
@name = name
end
def name #getter method
@name
end
end
obj1 = Movie.new('Forrest Gump')
p obj1.name #=> "Forrest Gump"
obj1.name = 'Fight Club' #=> undefined method `name=' for #<Movie:0x007f9937053368 @name="Forrest Gump"> (NoMethodError)
Defining a setter method inside a class makes it possible to set a value of an instance variable outside the class.
You can define a setter method like the code below.
class Movie
def initialize(name)
@name = name
end
def name #getter method
@name
end
def name=(name) #setter method
@name = name
end
end
obj1 = Movie.new('Forrest Gump')
p obj1.name #=> "Forrest Gump"
obj1.name = 'Fight Club'
p obj1.name #=> "Fight Club"
By using name=
, you can now assign a new value Fight Club
to obj1
.
Accessors
# this part I took everything from dev.to. They explain concept very well.
Accessors
are a way to create getter and setter methods without explicitly defining them in a class.
There are three types to accessors in Ruby.
attr_reader
automatically generates a getter method for each given attribute.attr_writer
automatically generates a setter method for each given attribute.attr_accessor
automatically generates a getter and setter method for each given attribute.
First, let’s take a look at attr_reader
!
As you can see in the code below, name
and year
are retrieved outside Movie
class even though there is no getter method for either of them. This is because attr_reader
generates a getter method for each given attribute.
class Movie
attr_reader :name, :year
def initialize(name, year)
@name = name
@year = year
end
end
obj1 = Movie.new('Forrest Gump', 1994)
p obj1.name #=> Forrest Gump
p obj1.year #=> 1994
Second, let’s see how attr_writer
works!
As I mentioned above, attr_witer
generates a setter method for each given attribute. Therefore you can assign new values to ob1
without explicitly writing setter methods for name
and year
!
class Movie
attr_reader :name, :year
attr_writer :name, :year
def initialize(name, year)
@name = name
@year = year
end
end
obj1 = Movie.new('Forrest Gump', 1994)
obj1.name = 'Fight Club'
obj1.year = 1999
p obj1.name #=> "Fight Club"
p obj1.year #=> 1999
Last but certainly not least, attr_accessor
does what attr_reader
and attr_writer
do with just one line of code! It will automatically generate a getter and setter mehod for each given attribute.
class Movie
attr_accessor :name, :year
def initialize(name, year)
@name = name
@year = year
end
end
obj1 = Movie.new('Forrest Gump', 1994)
obj1.name = 'Fight Club'
obj1.year = 1999
p obj1.name #=> "Fight Club"
p obj1.year #=> 1999
Initialize
# this part I took everything from learn co. They explain concept very well.
class Dog
end
snoopy = Dog.new #=> #<Dog:0x007f970a2edfd0>
The code above creates a new instance of the Dog
class and sets that object equal to a variable, snoopy
. If we want to give our dog a breed, we have to use the following code:
class Dog
def breed=(breed)
@breed = breed
end
def breed
@breed
end
end
snoopy = Dog.new #=> #<Dog:0x007f970a2edfd0>
snoopy.breed #=> nil
snoopy.breed = "Beagle"
snoopy.breed #=> "Beagle"
However, most dogs are born with a breed, not assigned a breed afterwards. How can we model the behavior of dogs being born with a breed in our Dog
class? If only there was a way for us to assign an individual dog a breed automatically upon creation, or instantiation.
Lucky for us, there is! It’s called the #initialize
method.
The #initialize
Method
We already know that any Ruby class can produce new instances of itself, via the <Class Name>.new
method, whether or not that class has an #initialize
method. However, if we want each instance of our class to be created with certain attributes, we must define an #initialize
method. An #initialize
method is a method that is called automatically whenever #new
is used.
Let’s define an #initialize
method that takes in an argument of a dog's breed and sets a @breed
variable equal to that argument. In other words, let's define our #initialize
method to contain the functionality of the #breed=
method, so that a dog instance will get a breed assigned to it right away when it is created, without us having to explicitly use the #breed=
method.
class Dog
def initialize(breed)
@breed = breed
end def breed=(breed)
@breed = breed
end def breed
@breed
end
end
Now, we can call #new
like this:
lassie = Dog.new("Collie")lassie.breed #=> "Collie"
References