Reputation: 43
I think my question is pretty simple but I'm not flash on the fundamentals.
I have a class and I want to store data in it from a loop and access those class objects outside of the loop. For example, I want code like below
class Numbers
attr_accessor :value
end
n = 1
while n < 10
p = Numbers.new
p.value = n
n += 1
puts p.value
end
but instead of iterating over each Number made inside of the loop, I want to store each class object and iterate over the collection outside of the initial loop. In my mind the code looks like this, but it's clearly not the right way to go about it.
class Numbers
attr_accessor :value
end
n = 1
while n < 10
Numbers.new
Numbers.value = n
n += 1
end
Numbers.each do |f|
puts f.value
end
I ask because I want to apply this technique to a more complex problem, thank you in advance for any help you can give.
Upvotes: 4
Views: 2279
Reputation: 2869
You can use ˙class variable˙ like collector for instances.
class Number
attr_accessor :value
@@numbers = []
def initialize(value = nil)
@value = value
@@numbers << self
end
def self.each
@@numbers.each do |inst|
yield inst
end
end
end
And then use
1.upto(9){|n| Number.new(n)}
Number.each{|inst| puts inst.value}
# => 1
# => 2
# => 3
# => 4
# => 5
# => 6
# => 7
# => 8
# => 9
Upvotes: 0
Reputation: 54223
Since your Number
value probably shouldn't be changed, you could just set value
when you create the Number
object :
class Number
attr_reader :value
def initialize(value)
@value = value
end
def to_s
@value.to_s
end
end
numbers = Array.new(10) { |i| Number.new(i) }
puts numbers
# =>
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
If you want Numbers between 1 and 9 :
numbers = (1..9).map { |i| Number.new(i) }
to_s
method has been defined in order to avoid getting :
#<Number:0x00000001363a70>
#<Number:0x00000001363a48>
#<Number:0x00000001363a20>
#<Number:0x000000013639f8>
#<Number:0x000000013639d0>
#<Number:0x000000013639a8>
#<Number:0x00000001363980>
#<Number:0x00000001363958>
#<Number:0x00000001363930>
when using puts
For basic arithmetic, you could add this method :
def +(other)
self.class.new(value + other.value)
end
to Number
.
Now you can type :
puts Number.new(1) + Number.new(2)
#=> 3
Upvotes: 1
Reputation: 27793
Try this
class Number
attr_accessor :value
end
numbers = (1..9).map do |n|
number = Number.new
number.value = n
number
end
How does this work?
map
is a loop that creates an array with the result from each iteration(1..9).map { |n| ... }
hence creates an array of 9 number objectsI guess you are new to Ruby so here is some help with classes and objects
Number
is a classnumber
is an objectNumber.new
creates an object that is an instance of class Number
value
is defined by Number
class and thus available on instances of that classnumber.value
is thus validNumber.value
is thus invalid and does not make senseSo your text should thus say
"I have a class and I want to create instances of it from a loop and access these instances outside of the loop. [...] But instead of iterating over each object made inside of the loop, I want to store each instance in an array and iterate over the array outside of the initial loop."
Upvotes: 4