CLASSES, INSTANCES, SETTERS, GETTERS, MARCOS... SAY WHAAA?!
Published: 2023-06-14 01:50:12

**<center>A WALK THROUGH TO REMEMBER</center>**
<center><hr/></center>

 Just when you thought JavaScript and React would throw you for a loop, you thought wrong... _Ruby_ decided to swing by and say "Hey girl, hey!". It's not that _Ruby_ is extremely difficult to take on, it's the idea of having to rewire your mind to tackle a whole new coding language. After all, no one said this would be an easy task. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ckkuz2011ruoep1y5cd.gif)

 I, and I'm sure many coders, can describe the beginning of learning  _Object Oriented Programming_ as shown in the example above. One fighting so hard to grasp the concepts of _OOP_ while having to take a few tumbles before allowing ourselves the time and patience to become one with the language. Let's be honest, this language is significantly bigger than ours and has extraordinary pro behaviors. However, we all must start somewhere and the key to starting "somewhere" is truly understanding the fundamentals and terminology in which we one day dream to master.
<br/>
 
**<center>CLASSES AND INSTANCES IN OBJECT ORIENTED PROGRAMMING</center>**
<center><hr/></center>

• A **`class`** in _OOP_ are models of the program that act as a blueprint for our objects _`(an instance)`_, the object's `attributes`, and methods that we can use on our `class` itself or `instances` of that `class`. That's right, there are `class methods` and `instance methods`. More on `class methods` in future lessons! 😉
<center><hr/></center>
• An **`instance`** in _OOP_ are objects _`(an instance)`_ of our `class` that holds detailed data about oneself acquired from `attributes` that are set with values after a new `instance` is `instantiated`.
<br/>

**<center>CLASS VISIUAL</center>**
<center><hr/></center>


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x51adfldwrbviaxfowog.jpeg)

**QUIZ TIME!!!**
What is a `class` in _OOP_?
**_A blueprint for our objects(`an instance`), the object's `attributes`, and methods that we can use on our `class` itself or instances of that `class`._**

 Before we jump into the visual of an `instance` it's crucial to know the work a `class` executes under the hood in order to `instantiate` an `instance` of a `class`. What exactly does it take to `instantiate` an `instance` of a `class`? We know that an `instance` _holds detailed data about oneself acquired from `attributes` that are set with values after a new `instance` is_ `instantiated`. But how would it be possible for our `instance` to know about its `attributes` when `instantiated`? This is when the _extraordinary pro behaviors_ of _OOP_ take center stage.
<br/>

**<center>CLASS VISIUAL: SETTER AND GETTER INSTANCE METHODS</center>**
<center><hr/></center>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq4qbg3dipfj1xk3tfkg.jpeg)

•A **`setter method`** is an `instance method`. Using this method allows us to set an `attribute` with a value of our `Person class instance` post `instantiation`. You may be looking at `@name` and thinking to yourself "Well that looks familiar, it's a variable!". Yes, like JavaScript this is a variable without a `var, const, or let` but instead begins with an `@` attached to the variable name. `@name` is known as an `instance variable`. 

 `@name` becomes an `attribute` available to an `instance` of the `Person class`. In this case, our `instance` can have an `attribute` of `name` that we can set equal to a `'string' value` _(or any data type value. In our case a name in real life, would be set to a 'string' data type)_ after we `instantiate` a new `instance` of the `Person class`. However, a `setter method` couldn’t be used to its best ability without its side kick...`getter method`.
<hr/>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9axpyk9eolpi3mpghi3.jpeg)

• A **`getter method`** is a method of an `instance` and pairs perfectly with a `setter method`. Think of the `setter method` as a _writer_. Its job is to take in an argument through its parameter, _write_ it to the `instance variable @name`, and store it away in memory. Let's take a look at what would happen if we `instantiate` an `instance` of the `Person class` without a `getter method`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfjj3771d19iq05itnk2.jpeg)

• Above we have our Person class set with just a setter method that creates an attribute with an instance variable. Now it's time to instantiate an instance of the Person class and set its name attribute equal to a 'string' value:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/naw3lap7dij4b4kll9eg.jpeg)

• Here we’re saving our new `instantiated instance` to a `local variable` called `justin`. We then take that variable with a value of our new `instance` and call it on our `setter method` within our `Person class`, `name=`. Remember the `setter method` has the _responsibility to take in an argument through its parameter, **write** it to the `instance variable @name`, and store it away in memory_. Although we would be able to set the `name attribute` for our new `instance` given the `setter method "name="`, what would happen if we called our `instance` on `justin.name` in order to see the `name value` of the `attribute` within the `instance` assigned:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ot9hda7x1goagn5wbv6b.jpeg)

•As you can see from the example above, we would get an error stating `"NoMethodError: undefined method 'name' for #<Person:0x000000011d969bf0 @name="Justin">
Did you mean?  name="`. When one sees `NoMethodError` we should assume as a coder there is no method existing that we can call this `instance` on. This is why the error is asking us "`Did you mean?  name=`".  Keep in mind `name=` being the `setter method`, is a completely different call than `name` being the `getter method`. Let's bring the `getter method` back into the equation of our `Person class`:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny3rs2lpl81zdpi5uwg6.jpeg)

•Now what would happen if we called our new `instantiated instance` on `justin.name`_?:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/76u3f8et55ytjqnvxszj.jpeg)

•As mentioned _`name=` being the `setter method`, is a completely different call than `name` being the `getter method`_. This is why a `setter method` and a `getter method` go hand and hand.  A `setter method` is a _writer_. Its job is to _take in an argument through its parameter, and _write_ it to the `instance variable @name`_. A `getter method` is a _reader_.  Its job is to _read_ what the `setter method` saved in memory for us, to the world.

 Without both `instance methods` working together we wouldn't have the full functionality we desire!

**<center>SETTER AND GETTER METHODS: MARCOS</center>**
<center><hr/></center>

 It may seem tedious to explicitly code out `setter` and `getter methods` within a class every time we'd want to set a new `instance` with an `attribute`. Surely, there has to be an easier way to write out both methods. If there is a will, there is most definitely a way. What is another method we could use that essentially is a `setter` and `getter method`? Drum roll, please!!! 🥁 `MARCOS`!!!``

• A **`marco`**, is an `instance method` that `implicitly` represents our `setter` and `getter methods`. Marcos allows the representation of both methods individually or in a lump sum. Are you confused yet? Let's break it down!

**<center>MARCOS SETTER AND GETTER METHODS VISUAL: MARCOS REPRESENTING ONE</center>**
<center><hr/></center>

 A `marco` can represent both a `setter` and `getter` individually. Typically it's best to start with a `setter method` within a `class model`. Our `setter method` is what allows us to create an `attribute` that our `instance` of the current `class` can adopt. We'll stick with our `name attribute` for this `instance`. Here's an example of a `marco` representing a `setter method implicitly`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r2h0lyowfstazrv2dbe.jpeg)

 It's important to know and understand a `setter method` is a _writer_. _Its job is to take in an argument through its parameter, _write_ it to the `instance variable @name`, and store it away in memory_. The same exception happens `implicitly` with `marcos`. As shown in the example above, the `marco` syntax for a `setter method` is `"attr_writer :attribute_name"`. All `attribute` names within this syntax must begin with a `colon`. We should now know if calling this method on an `instance`, the `instance` will adopt a name `attribute` when given a value equal to a `'string'` datatype:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lu3f0vcfz4jcsukdpuzo.jpeg)

 Intuitively, we know if we call our `instance` on `justin.name` in order to see the `name value` of the `attribute` on our `instance`, we would get an error stating `"NoMethodError: undefined method 'name' for #<Person:0x000000011d969bf0 @name="Justin">
Did you mean?  name="`:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6kue2oak8iwfuh7vnbx.jpeg)

**QUIZ TIME!!!**
Why are we getting the error `"NoMethodError: undefined method 'name' for #<Person:0x000000011d969bf0 @name="Justin">
Did you mean?  name="`?
**_There is no method that exists that we can call this instance on!_**

 This tells us we need a `marco` that `implicitly` represents a `getter method` within our `Person class`:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k1m37vanf5lie6k1k3e.jpeg)

 The `marco` syntax for a `getter method` is similar to the syntax for a `setter method` with a slight difference. Recall that a `getter method` acts as a _reader_. _Its job is to _read_ what the `setter method` saved in memory for us, to the world._ With that being said, what do you think the `marco` syntax would be for a `getter method`? Keep in mind the syntax will always start with `attr_`. This makes sense seeing that we're setting up an `attribute` within the `Person class` for our future `instances`. If the syntax for a `setter method` is `attr_writer` with `writer` being the _key_ word, what is a _key_ word that describes a `getter`? **READER**!: 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxk5smroshwzq625q4mu.jpeg)

 Notice we still need to include the name of the `attribute` beginning with a `colon` for our `implicit` `getter method` provided by `marcos`. If we think back to the `explicit` versions of our `setter` and `getter` in the `Person class`, both methods had a representation of the `instance variable @name`. This is crucial seeing that it helps keep the flow of `reading` and `writing` our `attributes` in sync. Now it's time to put our tag team `marcos` to the test!:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lvo29elmw4n7fiyhfa35.jpeg)

 If this isn't magic, I don't know what is! We were able to `initiate` an `attribute` for our future `instances` of our `Person class` given the `marco setter method`. Even more, we gracefully _read_ the value of the `attribute` to the world given our `marco getter method`. Job well done! However as coders, any opportunity given where we can make our code excel in ways we never thought possible, we take it! Although `marcos` is short-hand for writing explicit `setter` and `getter methods`, you would think there's one `marco` syntax that would implicitly set up both methods for us in lump sum. Bust out your inhalers because you'll be shocked that there is!
 
**<center>MARCOS SETTER AND GETTER METHODS VISUAL: MARCOS REPRESENTING BOTH LUMP SUM</center>**
<center><hr/></center>

 I know what you may be thinking if you're new to the coding world. _"WHY IN THE WORLD DID YOU NOT EXPLAIN MARCOS IN THE FIRST PLACE!"_ I get it. Yes, `marcos` is an easier set up than `explicit setter` and `getter methods`. However, _**we all must start somewhere and the key to starting "somewhere" is truly understanding the fundamentals and terminology in which we one day dream to master**_. Without understanding the fundamentals and terminology from which a method truly stems, how do we expect to understand how the _"easier"_ way of doing things actually works? Especially when it's implicit. You know what they say! Slow and steady wins the race.

 If you made it this far and truly have a grasp on the concepts of a `class`, `instance`, the origin of `setter` and `getter` methods, please indulge in our final `marco` that implicitly represents both a `setter` and `getter` lump sum.

 Let me introduce to you `attr_accessor`. The `marco` `attr_accessor` allows for a `setter` and `getter method` to be grouped into one `marco`. We no longer need to write two separate `marcos`, only one `marco` saving us time:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/acbuj10xpfvqn5hrpwvy.jpeg)

 Notice with this syntax we still need to apply a `colon` followed by the `attribute` name. With our `Parent class` and `marco attr_accessor` set up lets `instantiate' a new `instance` of our `class` saved to the variable, `justin`:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a0798rizbh68rzvde2kf.jpeg)

 As with our `explicit` and `implicit` methods before, our next step would be to take the variable `justin` with a value of our new `instance` and call it on our `setter method` `implicitly` nested in our marco, `name=`. This will allow us to officially initialize a `name attribute` with a `"string" value` within our the new `instance`:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4wwgarw8i1ylpn01fqt.jpeg)

 Last but not least it's time to _read_ to the world the value of the `name attribute` within our new `instance`! But how? **Take the variable `justin` with a value of our new `instance` and call it on our `getter method` implicitly nested in our `marco`, `name`**:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k620ffomjxr00fx6gqmv.jpeg)

**<center>THE END OF THE WALK</center>**
<center><hr/></center>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7bpnkay1741r8k44jnde.jpeg)

 We learned the role of a `class model` and the impact it has in order to `instantiate` an `instance`. It also has the ability to to act as a blue print which can hold `instance methods` that can be called on by an `instance` of our `class`. But what if we wanted our `instance` to have `attributes` to give the instance a volt packed with detailed data? We would have to imprint `setter` and `getter methods` within our `class`. Because an `instance` is only an object with an identifier number, it is our job to take advantage of different types of `instance methods` if we want to set `attributes`. To do so, we learned how to _write_ `explicit` _setter_ and _getter_ methods. One method has the responsibility of _writing_ an `attribute` and the other method has the responsibility of _reading_ the value of the `attribute` to the world.

 With being more than a few ways to write out `setter` and `getter methods`, we learned how to take on `marcos`. A `marco` is an _`instance method` that `implicitly` represents our `setter` and `getter methods`._ `Marcos` allows the representation of both methods individually or in a lump sum. Both syntax of a `marco` work under the hood exactly the same. However, writing an `attr_accessor` is less time consuming than writing `attr_writer` and `attr_reader`. Keep in mind the coding world is complexed with strategy and self coding awareness. There will be times using a specific `marco` syntax will come into play!

Until next time coders! Happy learning and coding! ✌🏽


## **Resources**
**1. Ruby Classes and Objects** [link](https://www.tutorialspoint.com/ruby/ruby_classes.htm)

**2. Ruby Setters and Getters** [link](https://www.geeksforgeeks.org/ruby-getters-and-setters-method/)

**3. Ruby Setters and Getters Link Two** [link](https://www.geeksforgeeks.org/ruby-getters-and-setters-method/)

**4.  attr_accessor, attr_writer and attr_reader** [link](https://www.rubyguides.com/2018/11/attr_accessor/)

**5.  attr_accessor, attr_writer and attr_reader Link Two** [link](https://bootrails.com/blog/ruby-attr-accessor-attr-writer-attr-reader/)