Return array with class instances [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 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

Related

Nested class initialize not being called [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am creating a custom Trie as follows:
# frozen_string_literal: true
class CustomTrie
attr_accessor :trie
def initialize(items)
end
def self.parse_to_trie(items)
end
def get(path)
end
class Node
attr_accessor :key, :parent, :children,
def initialize(key: '', parent: nil, children: [])
# This isn't being called, why?
#key = key
#parent = parent
#children = children
end
def is_parent?
end
def is_leaf?
end
def inspect
{key: #key, parent: #parent, children: #children}
end
end
class Trie
attr_accessor :root
def initialize(root = Node.new)
#root = root
end
def add(path)
end
def get(path)
end
end
end
However when I try calling CustomTrie::Node.new everything is initialized to nil instead of the default values, and when I try calling the constructor with values I get the error: "ArgumentError (wrong number of arguments (given x, expected 0))"
I'm sure I'm missing something obvious, but I haven't been able to identify what I'm doing wrong.
:facepalm:
It turns out it was because I had a comma after :children in my attr_accessor call.

how to make a class that makes multiple objects? [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 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">]

Access super variables using class object [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Heey I am new to Ruby. I need to create a factory method, which will return me an object of a class. Using that object I should be able to access the variables of the class. I have written the following code, but I surely have miss something.
class Super
##super_temp = 1
def Super.get_instance(world)
platform = world
if ##instance == nil
if platform==1
##instance = BaseA.new
else
##instance = BaseB.new
end
end
return ##instance
end
end
class BaseA < Super
##base_temp = 2
end
class BaseB < Super
##base_temp = 3
end
class Demo
def Demo.call_demo
obj = Super.get_instance(0)
puts "---------temp is #{obj.base_temp}"
end
end
Demo.call_demo
I need to retrieve the value of base_temp in class Demo.
Don't use ## (Why should we avoid using class variables ## in rails?) - # solves your problem just as easily.
Aside from that, all that is missing in your code is a getter:
class Super
#super_temp = 1
def Super.get_instance(world)
platform = world
if #instance == nil
if platform==1
#instance = BaseA.new
else
#instance = BaseB.new
end
end
return #instance
end
def base_temp
self.class.base_temp
end
def self.base_temp
#base_temp
end
end
class BaseA < Super
#base_temp = 2
end
class BaseB < Super
#base_temp = 3
end
class Demo
def Demo.call_demo
obj = Super.get_instance(0)
puts "---------temp is #{obj.base_temp}"
end
end
Demo.call_demo
# ---------temp is 3
The instance getter (implemented as self.class.base_temp) calls the class method base_temp of the instance's class. If we add prints of the internal products of the function, you can have some insights about its internals:
class Super
def base_temp
p self
p self.class
p self.class.base_temp
end
end
BaseA.new.base_temp
# #<BaseA:0x000000027df9e0>
# BaseA
# 2
BaseB.new.base_temp
# #<BaseB:0x000000027e38b0>
# BaseB
# 3

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"

invoke methods which are elements of an array [duplicate]

This question already has answers here:
How to call methods dynamically based on their name? [duplicate]
(5 answers)
Closed 8 years ago.
class Shop
def self.name
"kids-toy"
end
def self.postcode
1000
end
end
methods = ["name", "postcode"]
methods.each {|m|
mcall = "Shop.#{m}"
eval mcall
}
Is there any other way rather than calling eval to invoke methods which are elements of an array?
Using Object#send:
methods.each { |m| Shop.send(m) }
Yes, possible using Method#call method :
class Shop
def self.name
"kids-toy"
end
def self.postcode
1000
end
end
methods = ["name", "postcode"]
methods.each do |m|
p Shop.method(m).call
end
# >> "kids-toy"
# >> 1000
Shop.method(m) will give you an object of the class Method, now you can invoke the method #call on that method object.

Resources