Software Engineering Foundations - Week 2 Flashcards
What is the DRY rule?
Don’t Repeat Yourself and avoid repeating code
How do you create a class? What is the benefit of creating a class?
Class allows you to apply the DRY rule to avoid having to repeat bits of information over and over again.
To create a class we use the < “class” > keyword, and the name of a class must begin with a capital letter.
for example…
class Cat def initialize(name, color, age) @name = name @color = color @age = age end end
The @ symbol denotes an instance variable or attribute of our class
So for the example above, the Cat class will have attributes of @name, @color, @age
After initializing a class, how do we execute upon it and create instances or objects associated with the class?
Once you’ve initialized your class, you can create a new object under that class by using < class name >.new( attributes ).
The class name should be the singular of whatever object is being defined like “Cat” instead of “Cats.”
class Cat def initialize(name, color, age) @name = name @color = color @age = age end end
cat_1 = Cat.new("Sennacy", "brown", 3) cat_2 = Cat.new("Whiskers", "white", 5)
What is a Getter Method?
Way to get or return an attribute of an object belonging to a class. So in this example for Cat, we created the “get_name” method which calls on the “@name” attribute.
To execute on the getter method, we need to call on the cat INSTANCE (i.e. cat_1) instead of the class. It’s called, using this format “ < instance name >. “ -> cat_1.get_name
Without the getter method, there’s no way to refer or grab that attribute. A getter method can only return the value of an attribute. It cannot be used to modify the attribute like changing the cat’s age.
class Cat def initialize(name, color, age) @name = name @color = color @age = age end
def name
@name
end
end
def color
@color
end
end
cat_1 = Cat.new(“Sennacy”, “brown”, 3)
p cat_1.name # “Sennacy”
p cat_1.color #”brown”
What is a Setter Method?
IMPORTANT: You need to set the Getter method FIRST before you can create the Setter Method. The Setter Method will not work without the Getter method created first.
Allows you to change the value of an attribute after it’s already been “set”.
For the cat_1 example below, the age was originally 3, but say we want to change to 42. We can do that by creating a “setter” method where we add “age = number”
class Cat def initialize(name, color, age) @name = name @color = color @age = age end
def age = (number)
@age = number
end
end
cat_1 = Cat.new("Sennacy", "brown", 3) cat_1.age = 42 #this will change the value of the age from 3 to 42
What are ways to implement other types of methods within a class?
class Cat def initialize(name, color, age) @name = name @color = color @age = age end
def purr if @age > 5 puts @name.upcase + " goes purrrrrr..." else puts "..." end end end
cat_1 = Cat.new(“Sennacy”, “brown”, 10)
cat_1.purr # “SENNACY goes purrrrrr…”
cat_2 = Cat.new(“Whiskers”, “white”, 3)
cat_2.purr # “…”
What is a Class Variable?
An instance variable are denoted by @ and typically assigned insider the #initialize when creating a class. The instance variable is shared attribute across all objects of that class but the attribute itself can change from object to object. Like cars having different colors.
The CLASS VARIABLE sits outside of the #initialize (but still within the Class definition) and is denoted by @@. The @@ClassVariable is a single shared variable across all objects. E.g. the class variable -> @@num_wheels will be 4 and all cars under the Car class will have 4 wheels.
Class variables can be changed but once it changes, it’ll affect every instance created once it changes and will create in the future.
What is a Class Constant?
For safety, you can create a class constant which cannot be reassigned. A class constant name must be capitalized.
What are the three different ways to create a variable within a class?
- an @instance_variable will be a distinct variable in each instance of a class; changing the variable will only affect that one instance
e. g. @color, if you change the color for dog_1 but not dog_2, then it’ll only affect dog_1. - a @@class_variable will be shared among all instances of a class; changing the variable will effect all instances because all instances of the class
e. g. @@num_wheels will remain 4 for all cars in the class. But once you change to zero, it’ll affect all future objects of the class. - a CLASS_CONSTANT will be shared among all instances of a class, but cannot be changed
What is an Instance Method?
An instance method is a method that calls on an instance of a class.
In the example below, “#speak” is an instance method as it calls on the Dog instance we initialized using Dog.new.
If something is an instance of a class, it shares the same instance attributes (@) and can be created with < class name >.new
class Dog def initialize(name, bark) @name = name @bark = bark end
def speak
@name + “ says “ + @bark
end
end
my_dog = Dog.new(“Fido”, “woof”)
my_dog.speak # “Fido says woof”
What is a Class Method? What is the symbol associated with it?
A Class Method is a method that calls directly on the class by adding “self.” before the method name. Here’s the example “self.growl”. A Class method applies to all objects within the class.
ASSOCIATED WITH DOUBLE COLONS “::”
For notation we’ll use Dog::growl to denote that growl is a class method of Dog.
We then call on the method by using . = i.e. Dog.growl
Class#method_name means method_name is an instance method (e.g. my_dog.speak -> will only work with my_dog the object)
Class::method_name means method_name is a class method (e.g. Dog.growl -> applies to the whole class)
class Dog def initialize(name, bark) @name = name @bark = bark end
def self.whos_louder(dog_1, dog_2) if dog_1.bark.length > dog_2.bark.length return dog_1.name elsif dog_1.bark.length < dog_2.bark.length return dog_2.name else return nil end end
def name
@name
end
def bark
@bark
end
end
d1 = Dog.new(“Fido”, “woof”)
d2 = Dog.new(“Doge”, “much bork”)
p Dog.whos_louder(d1, d2) # “Doge”
How do you “monkey patch” or add methods within a class like class Array?
Create the method like normal but use “self” to refer to the Array or whatever class is being used.
What is Separation of Concerns?
A design principle that focuses on implement one class in a single file for greater organization and clarity.
See example below. Anything without the .rb ending is a folder like “project root” and
“other_animals”
project_root ├── pet_hotel.rb ├── cat.rb └── other_animals └── dog.rb
What is Require Relative?
“require_relative” is a method used to specify a path to another ruby file.
For example…see below. To run our hotel, we would just need to execute ruby pet_hotel.rb. Because pet_hotel.rb AS THE MASTER FILE requires cat.rb and dog.rb, the code in those files will also execute.
project_root/pet_hotel.rb
# Let's require the last two files, by specifying their path's relative to this pet_hotel.rb file require_relative "./cat.rb" require_relative "./other_animals/dog.rb"
class PetHotel def initialize(name) @name = name @guests = [] end
What is the difference between running just “require” and “require_relative”?
We use the plain require because we run the code using RSPEC via bundle exec rspec. RSPEC will automatically run the code in a certain configuration where it will automatically know to look inside of the /lib folder. In fact, RSPEC is designed to be used where you have a separate /spec and /lib folders. To get into the nitty gritty details, RSPEC will configure the $LOAD_PATH for us.
As a rule of thumb, we’ll use the plain require where gems are involved. In the previous sections that used the byebug gem, we had to write require “byebug” to access the debugger. It’s obvious that we don’t have an explicit byebug.rb file in those old projects. This is because ruby already knows where to find byebug through the $LOAD_PATH.
What is the built-in method for user input?
“gets” - built-in method will halt execution of the code and allows the user to type characters until they hit enter.
p “Enter your name:”
name = gets
p “hello “ + name
What’s a nuisance of getting user input? How do we deal with it?
When user hits the “enter” button, it’ll translate to adding “\n” a newline code to the end of the user-typed response.
Need to add .chomp at the end to remove the newline or carriage return characters.
puts “Enter ‘yes’ or ‘no’”
response = gets.chomp
if response == "yes" puts "yup!" elsif response == "no" puts "nah!" else puts "I'm sorry, my responses are limited." end
What happens with a user inputs a number? How do we deal with it?
A common error is when a user inputs an integer and it automatically comes back as a string.
Need to convert to an integer using “.to_i”
puts “Enter a number: “
num = gets.chomp.to_i
puts 2 * num
What are the two pillars of Object Oriented Programming (OOP)?
- Abstraction = abstraction is the process of exposing essential features of an object while hiding inner details that are not necessary to using the feature. Take this analogy: Many drivers do not understand the mechanical details of how a steering wheel works, but they can still use the steering wheel to drive a car. In a similar way, our classes should have methods that are simple to use because they hide complex logic inside of them.
Another example, Array is a class and Array#include? is a method that we feel comfortable using although we do not know the exact implementation details within the method
- Encapsulation = is like a protective shield that prevents the data from being accessed by the code outside the shield.
Encapsulation can be achieved by declaring all the variables in the class as private and writing public methods in the class to set and get the values of variables.
For example, if there was a Queue class and within the class methods to define adding and removing people from the line. To avoid havoc, the queue class will avoid any getter or setter methods to be able to enforce the rules and keep it secure.