how to make a class that makes multiple objects? [closed] - ruby

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
How can I make a class that makes multiple classes. I have this:
class Person
attr_accessor :name
#name = name
def initialize
Person.new
Person.new
Person.new
Person.new
Person.new
Person.new
Person.new
Person.new
end
end
but that returns stack level to deep.

I wasn't clear where you wanted to get the names from -- External file? Manual Input? Database?
In any case, you could probably do something like:
class Person
attr_accessor :name
def initialize(name)
self.name = name
end
end
##some sort of input goes here and creates the array of names
arrayofnames = [name1,name2,name3]
arrayofnames.each do |person|
Person.new(person)
end
As part of the same enumeration you could put each new person into an array or store them somewhere else for later use. Here I built the class and added the people to it separately, although you could probably build the same enumeration into the class itself.
Hope that helps,

The problem that you are facing is that you are creating a person which in turn is creating 10 other person objects which are all returning 10 person objects. This continues on indefinitely.
What you want is:
class Person
attr_accessor :name
#name = name
end
class People
#people
def initialize()
people = []
for i in 0..10
people[i] = Person.new
end
end
end
This creates another object that in turn contains 10 Person objects. This way there is no way for the same recursive problem to happen.

First of all, this is your Person class:
class Person
attr_accessor :name
def initialize(name)
#name = name
end
end
If you want another class to create x number of Person instances you can use the following PeopleCreator class:
class PeopleCreator
def self.create_person_for(names)
new.create(names)
end
def create(names)
names.map { |name| Person.new(name) }
end
end
I've used a class method in the PeopleCreator to be able to easily call the following:
names = %w(John Jane Jake)
PeopleCreator.create_person_for(names)
# => [#<Person:0x0000000a743150 #name="John">, #<Person:0x0000000a743128 #name="Jane">, #<Person:0x0000000a743100 #name="Jake">]

Related

Ruby self.name or #name [duplicate]

This question already has answers here:
Instance variable: self vs #
(6 answers)
Closed 5 years ago.
I have a question about what the best way is to reference a class variable in Ruby.
Here is a class I made:
class Person
attr_accessor :name
def initialize(name)
#name = name
end
def say_name
puts #name
end
def say_name2
puts self.name
end
end
bob = Person.new("Bob")
bob.say_name
=> "Bob"
bob.say_name2
=> "Bob"
Both of the "say_name" methods seems to work as intended. Why use the #variable vs the self.variable??
attr_accessor :name just creates method name, which returns #name variable, something like
def name
#name
end
instead of you.
Without attr_accessor both self.name and name will not work and return NoMethodError.
#name will work in all cases.

How can I create a to_s with an instance variable pointing to an array of objects from another class?

With the code below, I would like to create a to_s method that prints out information as such:
Southside has 3 team members.
Those members are: Dario, who is 22 years old. Ted, who is 21 years old. Bob, who is 44 years old.
Currently, I get this:
Southside has 3 team members.
Those members are:
[#<Person:0x000000025cd6e8 #name="Dario", #age=22>, #<Person:0x000000025cd670 #name="Ted", #age=21>, #<Person:0x000000025cd620 #name="Bob", #age=44>].
#<Team:0x000000025cd7d8>
The part I'm finding difficult is accessing the instance variables of the Person class objects that are in the Team members array.
Here are the two classes:
class Team
attr_accessor :name, :members
def initialize(name)
#name = name
#members = []
end
def <<(person)
members.push person
end
def to_s
puts "#{#name} has #{#members.size} team members."
puts "Those members are: #{#members}."
end
end
class Person
attr_accessor :name, :age
def initialize(name, age)
#name = name
#age = age
end
end
south_side_bowlers = Team.new("Southside")
south_side_bowlers << Person.new("Dario", 22)
south_side_bowlers << Person.new("Ted", 21)
south_side_bowlers << Person.new("Bob", 44)
puts south_side_bowlers
Define to_s ("#{#name}, who is #{#age} years old") for the Person class. Then you can do #members.map{ |m| m.to_s}.join('. ')
First off, you don't want to have puts in a to_s method. Instead just return the string. Second, the variable members is probably not actually what you want outputted in the method. Try this instead
def to_s
%Q(#{#name} has #{#members.size} team members. Those members are #{#members.map{|i| "#{i.name} who is #{i.age}"}.join(', ')})
end

What is wrong with this Ruby code 2? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What is wrong with this code?
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{name}"
end
end
Write the code as
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{#name}" # <~~ you missed `#` before name.
end
end
If you write only name(instead of #name), Ruby will try to look for a local var named as name, but you didn't define any. Then it will try to check if any method you have defined as name or not, that also not present. So finally you will get
undefined local variable or method `name'
Here is an example after the fix :
#!/usr/bin/env ruby
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{#name}"
end
end
Person.new("Raju").greet('Welcome!') # => "Hi Welcome!, my name is Raju"

What is the most elegant way to get the value in an array, minimizing a certain class attribute?

Say I have the following class:
class Person
def initialize(name, age)
#name = name
#age = age
end
def get_age
return #age
end
end
And I have an array of Person objects. Is there a concise, Ruby-like way to get the person with the minimum (or maximum) age? What about sorting them by it?
This will do:
people_array.min_by(&:get_age)
people_array.max_by(&:get_age)
people_array.sort_by(&:get_age)
Your question has been answered properly but, since you are interested in doing things in a Ruby-like way,
I am going to show you a better Ruby-like way to define your Person class.
If do you do not have behaviour (methods, etc.) in your class, the simplest way is using a Struct:
Person = Struct.new(:name, :age)
# example of use
person = Person.new("My name", 21)
Otherwise create a custom class like this, using attr_reader and a hash of arguments:
class Person
attr_reader :name, :age
def initialize(args = {})
#name = args[:name]
#age = args[:age]
end
end
# example of use
person = Person.new(:name => "My name", :age => 21)
Assuming you got an array named array having 5 different instances of Person.
To get the older person
for person in array
olderperson = person if maxperson.get_age < person.get_age
end
And for sorting them
array.sort! { |a,b| a.get_age <=> b.get_age }
Something like below:
youngest_person = people.select { |p| p.get_age == people.map(&:get_age).min }

Return array with class instances [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
i have simple, how to return array with class instances ? I'm trying to return the array, but this variable return an empty array.
For example :
class Library
def initialize
##books = []
end
def all
##books
end
def add_book(arg = {})
#book = Book.new(arg)
##books << #book
end
end
class Book
attr_accessor :name, :year, :author, :content
def initialize( arg = {})
#name = arg[:name]
#year = arg[:year]
#author = arg[:author]
#content = arg[:content]
end
end
##books is a Library class variable. I am using method add_book to put books into #books, but how can i return array of these instances ? Sorry for bad english.
Thanks in advance !
When you call the method new to create a new object, ruby runs the initialize method. Since the initialize method sets ##books to an empty array, of course Library.new.all will return an empty array.
Class variables are shared by all instances of a class, so it doesn't make sense to be resetting it when you initialize a new Library as you'd be zeroing out the books stored in all other Library instances. From your usage it looks like you want a plain instance variable:
class Library
def initialize
#books = []
end
# you could replace this method with a `attr_reader :books`
def all
#books
end
# consider changing the method signature to accept a Book instance
def add_book(arg = {})
#books << Book.new(arg)
end
end

Resources