سؤال

I am working on class methods.

I am trying to count the number of created instances of a class. I am able to do this by creating a counter variable in the initialize method.

The problem arises when I reassign the variable originally assigned to one class instance. Because the initialize method is called twice, it does not recognize that the variable is simply being reassigned to another class instance.

class Ticket
    attr_accessor :price
    attr_reader :event, :venue

    @@count = 0
    @@tickets = {}

    def initialize(event, venue)
        @event = event
        @venue = venue

        @@count += 1
    end

    def self.count
        @@count 
    end
end

a = Ticket.new("Michael Buble", "Staples")

a = Ticket.new("Frank Sinatra", "Madison Square Garden")

puts "Ticket count of #{Ticket.count}"

When I run the above code in IRB, it gives me a Ticket count of 2 (as expected). How do I change my code so that it recognizes the overwrite?

NOTE: I know that this question has been asked before for Objective C, but the reassignment aspect of the question adds a different element to the problem. Let me know otherwise.

هل كانت مفيدة؟

المحلول 2

In the real world you wouldn't be counting instances in memory, you'd be asking a database how many exist. You need to think in terms of a database.

Your use of a to repeatedly contain the Ticket instance is wrong. You should be using an Array, Hash or Set to maintain the list, then ask the container how many exist:

require 'set'

class Ticket
  attr_accessor :price
  attr_reader :event, :venue

  @@tickets = Set.new

  def initialize(event, venue)
    @event = event
    @venue = venue

    @@tickets << self
  end

  def delete
    @@tickets.delete(self)
  end

  def self.count
    @@tickets.size
  end

end

a = Ticket.new("Michael Buble", "Staples")
b = Ticket.new("Frank Sinatra", "Madison Square Garden")

puts "Ticket count of #{Ticket::count}"
b.delete
puts "Ticket count of #{Ticket::count}"

You can build this out by adding ways to retrieve a particular instance from @@tickets, add a to_s so you can list them, but, in the end, you'll want to use a real database. If your code were to crash for any reason, your entire list of tickets would disappear, which would be unacceptable in real life.

نصائح أخرى

ObjectSpace.each_object(Ticket).count

Will give you the count of object currently in memory. On testing in IRB I find it runs into the problem you describe, objects persist in memory even though you have assigned a new one to the variable. Technically the object still exists, even though you assign a new instance to the variable "a".

See this article: Deleting an object in Ruby The answers have plenty of info about what you are trying to do.

If you really want to count live instances of the Ticket class (for reasons I cannot fathom), @Beartech has the right idea:

class Ticket
  attr_reader :event, :venue

  def initialize(event, venue)
    @event = event
    @venue = venue
  end   

  def self.count_live_instances
    ObjectSpace.garbage_collect
    ObjectSpace.each_object(self).to_a.size
  end
end

a = Ticket.new("Michael Buble", "Staples")
b = Ticket.new("Cher", "Canadian Tire Center")
a = Ticket.new("Frank Sinatra", "Madison Square Garden")

puts "Ticket instances count = #{Ticket.count_live_instances}" # => 2

It is essential to garbage-collect before invoking ObjectSpace#each_object. If you are skeptical, insert p ObjectSpace.each_object(self).to_a.size as the first line of self.count_live_instances. It will print 3.

(There is also a method ObjectSpace#count_objects. This method returns a hash like this one: {:TOTAL=>56139,..., :T_ARRAY=>3139,..., :T_ICLASS=>32}. Unfortunately, the keys are "object types"; you won't find :TICKET among them.)

class Gs def self.method1 code... end def self.method2 code... end def self.method3 code... end end Gs.new p Gs.singleton_methods.count

The Gs.singleton_methods.count will print 3 it will count the singleton methods,if we use the self keyword or classname.method name..

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top