Ruby class instance and inheritance - ruby

I want to make a subclass to add attributes to the subclass in addition to the superclass. this is what I've tried:
Version I:
class Person
attr_reader :first_name, :last_name, :age
def initialize (first_name, last_name, age)
#first_name = first_name
#last_name = last_name
#age = age
end
end
class Musician < Person
attr_reader :first_name, :last_name, :age, :instrument
def initialize (first_name, last_name, age, instrument)
super
#instrument
end
end
Version II
class Person
ATTRS = ['first_name', 'last_name', 'age']
def attributes
ATTRS
end
end
class Musician < Person
ATTRS = ['instrument']
def attributes
super + ATTRS
end
end
Neither of these work.

In version 1 try
class Musician < Person
attr_reader :instrument
def initialize(first_name, last_name, age, instrument)
# Pass arguments to the super class' constructor!
super first_name, last_name, age
#instrument = instrument
end
end
Thanks to attr_reader :first_name, :last_name, :age in Person Musician will have those three accessors available because of inheritance.

Related

how to add created objects in static array?

How can i add all created objects in self.persons ?
class Person
attr_accessor :name, :last_name, :age
def initialize(name, last_name, age = "no_age")
##persons = []
#name = name
#last_name = last_name
#age = age
add(#name, #last_name, #age)
end
def self.persons
##persons
end
private
def add(name, last_name, age)
##persons << [name, last_name, age]
end
end
person1 = Person.new("name1", "lastname1", 12)
person2 = Person.new("name2", "lastname2", 16)
p Person.persons # => [["name2", "lastname2", 16]]
You can use "conditional assignment operator" to check if array is nil.
def initialize(name, last_name, age = "no_age")
##persons ||= []
#name = name
#last_name = last_name
#age = age
add(#name, #last_name, #age)
end

Ruby wrong number of arguments

I'm trying to to create my getters and setters using attr_accessor. I want to assign a value to my variables.
Here is my code:
class Person
def initialize(name)
attr_accessor :name
end
def initialize(age)
attr_accessor :age
end
end
person1 = Person.new
person1.name = "Andre"
person1.age = 22
I get some trouble though. My error is:
q5.rb:6:in `initialize': wrong number of arguments (given 0, expected 1) (ArgumentError)
This is what you're trying to do:
class Person
attr_accessor :name, :age
end
person1 = Person.new
person1.name = "Andre"
person1.age = 22
An alternative approach, for example, could be:
class Person
attr_accessor :name, :age
def initialize(name, age)
#name = name
#age = age
end
end
person1 = Person.new("Andre", 22)
The error you're seeing is because you defined (and then re-defined) an initialize method that is expecting one parameter:
def initialize(name)
and then tried to create an object without supplying a parameter:
person1 = Person.new

railstutorial.org 4.4.5 exercise 1

In the exercise, we have to add a method called "full_name" which takes the first and last name attributes and separates them by a space.
class User
attr_accessor :first_name, :last_name, :email
def initialize(attributes = {})
#first_name = attributes[:first_name]
#last_name = attributes[:last_name]
#email = attributes[:email]
end
def full_name
"#{#first_name} #{#last_name}"
end
def formatted_email
full_name "<#{#email}>"
end
end
I created 2 separate first and last name attributes, I defined the full_name method, I am stuck on how to implement that method into the "formatted_email" method. I tried
"full_name <#{#email}>"
but was unsuccessful. Where should I put the full_name?
def formatted_email
"#{full_name} <#{#email}>"
end

Creating an object from a class which is inherited ruby

Im struggling on understanding (after googling) on how to implement this: I have a class:
class Student
# constructor method
def initialize(name,age)
#name, #age = name, age
end
# accessor methods
def getName
#name
end
def getAge
#age
end
# setter methods
def setName=(value)
#name = value
end
def setAge=(value)
#age = value
end
end
And lets say I have another class which inherits from Student
class Grade < Student
#constructor method
def initialize(grade)
super
#grade = grade
end
# accessor methods
def getGrade
#grade
end
# setter methods
def setGrade=(value)
#grade = value
end
end
I understand how to build an abject:
student = Student.new(name, age)
How can I build this Student (that I have just created) a Grade object associated with the student and how would I call the inherited object, for example i wanted to:
puts 'student name and associated grade'
I know I can place the grade variable within the Student class, but for the purpose of learning im doing it this way.
This code would do what you wanted:
class Grade
attr_accessor :value
def initialize value
#value = value
end
end
class Student
attr_accessor :name, :age, :grade
def initialize name, age, grade
#name, #age, #grade = name, age, Grade.new(grade)
end
end
st = Student.new 'John', 18, 5
puts "student #{st.name} and associated grade #{st.grade.value}"
First off, no need to define accessors in Ruby like that, it's far from idiomatic. Let's clean that up first:
class Student
attr_accessor :name, :age
def initialize(name, age)
#name =name
#age = age
end
end
class Grade
attr_accessor :value
def initialize(grade)
#value = grade
end
end
Secondly it doesn't seem like Grade should inherit from Student at all, just adjust the latter to also store a Grade instance variable:
class Student
attr_accessor :name, :age, :grade
def initialize(name, age, grade = nil)
#name =name
#age = age
#grade = grade
end
end
You can then instantiate a student like this:
student = Student.new("Test", 18, Grade.new(1))
Or because of the default value you leave off the grade and assign it later:
student = Student.new("Test", 18)
# later
student.grade = Grade.new(1)

Ruby Search by using input

modify this code to create search by first name using user input output must show age and title
# A simple Employee class
class Employee
attr_reader :first_name, :last_name, :title, :age
def initialize(fname, lname, title, age)
#first_name = fname
#last_name = lname
#title = title
#age = age
end
# A string representation of the Employee object
def to_s
"#{first_name} #{last_name}, #{title}, #{age}"
end
end
# The collection class for Employee objects
class Employees
include Enumerable
def initialize
#employees = []
end
# Add Employee objects to the collection
def <<(employee)
#employees << employee
end
# Method mandated by the Enumerable module
def each
#employees.each { |e| yield(e) }
end
end
employees = Employees.new
employees << Employee.new('Anita', 'Baker', 'President', 48)
employees << Employee.new('Frank', 'Gifford', 'Director', 58)
employees << Employee.new('Barbara', 'Eden', 'Secretary', 34)
employees << Employee.new('George', 'Clooney', 'Project Manager', 37)
employees << Employee.new('Emily', 'Davies', 'Programmer', 28)
employees << Employee.new('David', 'Faber', 'Programmer', 55)
employees << Employee.new('Cindy', 'Adams', 'Programmer', 33)
employees << Employee.new('Helen', 'Hamilton', 'Business Analyst', 42)
You have already done all the necessary work by implementing Enumerable interface. Just accept user input and call the Enumerable#find method:
fname = gets.chomp
e = employees.find {|i| i.first_name == fname}

Resources