📖 Scenario: Imagine you have a simple Ruby program that uses a class to represent a book. Later, you want to add a new feature to this class without changing the original code. Ruby lets you reopen classes to add or change methods anytime.
🎯 Goal: You will create a class called Book, then reopen it to add a new method. Finally, you will print the result of calling this new method on a Book object.
📋 What You'll Learn
Create a class called Book with an initialize method that takes title and author parameters and saves them as instance variables.
Create an instance of Book with title 'Ruby Basics' and author 'Jane Doe'.
Reopen the Book class to add a method called description that returns a string combining the title and author.
Print the result of calling description on the Book instance.
💡 Why This Matters
🌍 Real World
Reopening classes lets developers add or fix features in existing code without rewriting it. This is useful when working with libraries or frameworks.
💼 Career
Understanding open classes is important for Ruby developers to customize behavior and maintain code efficiently.
Progress0 / 4 steps
1
Create the Book class with initialize
Create a class called Book with an initialize method that takes title and author parameters and assigns them to instance variables @title and @author.
Ruby
Hint
Use class Book to start the class. Define initialize with two parameters. Use @title = title and @author = author inside the method.
2
Create a Book instance
Create a variable called my_book and assign it a new Book object with title 'Ruby Basics' and author 'Jane Doe'.
Ruby
Hint
Use my_book = Book.new('Ruby Basics', 'Jane Doe') to create the object.
3
Reopen Book class to add description method
Reopen the Book class and add a method called description that returns a string in the format: "Title: [title], Author: [author]" using the instance variables @title and @author.
Ruby
Hint
Write class Book again to reopen it. Define def description and return the formatted string using "Title: #{@title}, Author: #{@author}".
4
Print the description of my_book
Write a puts statement to print the result of calling description on the my_book object.
Ruby
Hint
Use puts my_book.description to print the description.
Practice
(1/5)
1. What does it mean to reopen a class in Ruby?
easy
A. You write the class again to add or change methods without deleting the original.
B. You create a new class with the same name but different methods.
C. You delete the old class and replace it with a new one.
D. You make a copy of the class and modify the copy only.
Solution
Step 1: Understand Ruby class behavior
In Ruby, classes are open, meaning you can write the class again to add or change methods.
Step 2: Identify what reopening means
Reopening a class means modifying the existing class by adding or replacing methods without deleting it.
Final Answer:
You write the class again to add or change methods without deleting the original. -> Option A
Quick Check:
Reopen class = add/change methods anytime [OK]
Hint: Reopen means add or change methods by rewriting class [OK]
Common Mistakes:
Thinking reopening creates a new separate class
Assuming reopening deletes the old class
Confusing reopening with copying a class
2. Which of the following is the correct syntax to reopen the String class and add a method shout that returns the string in uppercase with exclamation?
easy
A. class String
def shout
self.upcase + "!"
end
end
B. def String.shout
self.upcase + "!"
end
C. class String
def shout
upcase!
end
end
D. class String
def shout
self + "!"
end
end
Solution
Step 1: Check class reopening syntax
To reopen a class, write class ClassName again and define methods inside.
Step 2: Verify method definition and behavior
Method shout should return uppercase string plus exclamation, so self.upcase + "!" is correct.
Final Answer:
class String
def shout
self.upcase + "!"
end
end -> Option A
Quick Check:
Reopen class + define method correctly = class String
def shout
self.upcase + "!"
end
end [OK]
Hint: Use class name again and define method inside [OK]
Common Mistakes:
Defining method outside class
Using destructive method like upcase! which changes string
Not returning uppercase string with exclamation
3. What will be the output of this Ruby code?
class Array
def first_two
self[0..1]
end
end
arr = [10, 20, 30, 40]
puts arr.first_two.inspect
medium
A. [10]
B. [10, 20]
C. [20, 30]
D. nil
Solution
Step 1: Understand method added to Array
The method first_two returns elements at index 0 and 1 using self[0..1].
Step 2: Apply method on given array
Array is [10, 20, 30, 40], so first_two returns [10, 20].
Final Answer:
[10, 20] -> Option B
Quick Check:
Array slice 0..1 = first two elements [OK]
Hint: Slice array 0..1 to get first two elements [OK]
Common Mistakes:
Confusing index ranges and getting wrong slice
Expecting single element instead of array
Thinking method returns nil
4. This code tries to reopen the Integer class to add a method double. What is wrong?
class Integer
def double
self * 2
end
end
puts 5.double()
medium
A. Method double should be defined as a class method, not instance method.
B. You cannot reopen built-in classes like Integer.
C. Nothing is wrong; it will print 10.
D. The method double uses wrong syntax for multiplication.
Solution
Step 1: Check if reopening Integer is allowed
Ruby allows reopening built-in classes like Integer to add instance methods.
Step 2: Verify method and usage
Method double multiplies self by 2, and calling 5.double() returns 10.
Final Answer:
Nothing is wrong; it will print 10. -> Option C
Quick Check:
Reopen Integer + instance method works = 10 output [OK]
Hint: Reopen built-in classes freely; instance methods work [OK]
Common Mistakes:
Thinking built-in classes cannot be reopened
Confusing instance and class methods
Assuming syntax error in multiplication
5. You want to reopen the Hash class to add a method symbolize_keys that returns a new hash with all string keys converted to symbols. Which code correctly does this?
hard
A. class Hash
def symbolize_keys
each_with_object({}) do |(k, v), h|
h[k.to_sym] = v
end
end
end
B. class Hash
def symbolize_keys
map { |k, v| [k.to_sym, v] }
end
end
C. class Hash
def symbolize_keys
keys.map(&:to_sym)
end
end
D. class Hash
def symbolize_keys
self.transform_keys(&:to_sym)
end
end
Solution
Step 1: Understand the goal
We want a method that returns a new hash with string keys converted to symbols.
Step 2: Check each option's correctness
class Hash
def symbolize_keys
each_with_object({}) do |(k, v), h|
h[k.to_sym] = v
end
end
end manually builds a new hash but misses handling non-string keys safely. class Hash
def symbolize_keys
map { |k, v| [k.to_sym, v] }
end
end returns an array, not a hash. class Hash
def symbolize_keys
keys.map(&:to_sym)
end
end returns only keys as symbols, not a hash. class Hash
def symbolize_keys
self.transform_keys(&:to_sym)
end
end uses transform_keys(&:to_sym), a built-in method that correctly returns a new hash with symbol keys.
Final Answer:
class Hash
def symbolize_keys
self.transform_keys(&:to_sym)
end
end -> Option D
Quick Check:
Use transform_keys(&:to_sym) for symbol keys [OK]
Hint: Use transform_keys(&:to_sym) to convert keys easily [OK]
Common Mistakes:
Returning array instead of hash
Not returning a new hash
Ignoring keys that are not strings
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.