20. Extra Step for Fun - Iterate thru Instance Variables of a Class


#1



Bringing this one step further from the lessons taught to us, how can we iterate thru all of the instance variables? For example, after building a collection of instance variables for the Class Message, what if we wanted to return a list of ALL the messages that were sent to?


https://www.codecademy.com/en/courses/ruby-beginner-en-MFiQ6/3/5?curriculum_id=5059f8619189a5000201fbcb


Replace this line with your code.


#2

@jaydacoder,

You will have to keep track of your messages
here an Array is used....

 emails=[]
 class Message
    @@messages_sent = 0
    def initialize(from, to, text)
        @@messages_sent += 1
        @from=from
        @to=to
        @text=text
        #status 0=created
        #status 1=sent
        #status 3=tryAgain
        @status=0
    end
      def self.number_of_messages
    # Return your class variable on line 13
        puts "Number of Email instances: #{@@messages_sent}" 
      end
      def self.message_nr
    # Return your class variable on line 13
        return "#{@@messages_sent}" 
      end
      def status=status_code
    # Return your class variable on line 13
        @status= status_code 
      end
 end

 class Email < Message
    def initialize(from, to, text)
        super
    end
  end
  #Creating the Message
  my_mail= Email.new("c","d","Message-text-#{Message.message_nr}")
  emails.push my_mail
  my_mail= Email.new("c","d","Message-text-#{Message.message_nr}")
  emails.push my_mail
  #How many messages were created
  Message.number_of_messages
  #How does the Message look like
  puts "== created =========================="
  puts "From  : #{emails[0].instance_variable_get("@from")}"  
  puts "Text  : #{emails[0].instance_variable_get("@text")}"
  puts "Status: #{emails[0].instance_variable_get("@status")}"
  puts "== sending =========================="
  emails[0].status=1
  puts "== check-status ====================="
  puts "From  : #{emails[0].instance_variable_get("@from")}"  
  puts "Text  : #{emails[0].instance_variable_get("@text")}"
  puts "Status: #{emails[0].instance_variable_get("@status")}"

#3

@leonhard.wettengmx.n Thanks for the explanation. It's a lot of info for a beginner like me to absorb, feeling overwhelmed. Basically I want to know how to run a report (in simplest terms possible). I've come up with a scenario below. On Line 24 where it shows emails.each { |from, to| puts from } is the step where I'm having problems with. I'm trying to figure out how to get it to return a list of from. It should return for example...

From: Ruby
From: Richard
From: John

I've pasted below what I have so far using a simpler example.

emails = []

class Message
    @@msgs_sent = 0
    def initialize(from, to)
        @from = from
        @to = to
        @@msgs_sent += 1
    end
    def self.nr_of_msgs
        @@msgs_sent
    end 
end

my_message = Message.new("Ruby", "Jane")
emails << my_message
my_message = Message.new("Richard", "Tim")
emails << my_message
my_message = Message.new("John", "Anna")
emails << my_message

puts "#{Message.nr_of_msgs} messages were sent!"

emails.each { |from, to| puts "From: #{from}" }`

#4

@jaydacoder,
What you should understand::
With emails = [] you create an =empty= Array.

With emails << my_message you =append= an object to this Array.
( actually you are adding the =pointer= to a memory-address where the object lives )
that is why if you use
puts emails[0]
you will get the output
#<Message:0x12fdb8>
and you can determine that
at memory-address 0x12fdb8
you will find an Instance of the Message Class

Now as Ruby :tm: is a strictly Class driven language,
and you want to get access to Data of that specific Message Instance
you will have to define a getter Method within the Message Class
( a getter is also called an accessor Method )
( if you want to manipulate the Value you will need a setter or mutator Method )

[================= the code ============================]

emails = []

class Message
    @@msgs_sent = 0
    def initialize(from, to)
        @from = from
        @to = to
        @@msgs_sent += 1
    end
    def display_from()
        "From: " + @from
    end
    def self.nr_of_msgs
        @@msgs_sent
    end 
end

# Instantiate the Message Class
my_message = Message.new("Ruby", "Jane")
# append the Message-Instance to the =emails= Array
emails << my_message
# now look at element-0 of the =emails= Array
puts emails[0]
# element-0 of the =emails= Array using the =getter= Method
puts emails[0].display_from()
#==========================================
#directly append the new Instance to the =emails= Array
emails << Message.new("Richard", "Tim")
#==========================================
my_message = Message.new("John", "Anna")
emails << my_message

puts "#{Message.nr_of_msgs} messages were sent!"

emails.each { |message_object| puts message_object.display_from() }

#5

Thanks so much. With your help I finally figured it out.


#6

@leonhard.wettengmx.n Just one more question.Why the parenthesis after display_from?

I tried without () and it works both ways. display_from() and display_from are both accepted.


#7

@jaydacoder,
Read a discussion on the subject
http://stackoverflow.com/questions/340624/do-you-leave-parentheses-in-or-out-in-ruby