Ruby 如何在不计算重新分配的情况下计算类的实例数?

Ruby 如何在不计算重新分配的情况下计算类的实例数?,ruby,class,methods,instances,Ruby,Class,Methods,Instances,我正在研究课堂教学法 我试图计算一个类的已创建实例的数量。我可以通过在initialize方法中创建一个计数器变量来实现这一点 当我重新分配最初分配给一个类实例的变量时,问题就出现了。因为initialize方法被调用了两次,所以它无法识别变量只是被重新分配给了另一个类实例 class Ticket attr_accessor :price attr_reader :event, :venue @@count = 0 @@tickets = {} de

我正在研究课堂教学法

我试图计算一个类的已创建实例的数量。我可以通过在
initialize
方法中创建一个计数器变量来实现这一点

当我重新分配最初分配给一个类实例的变量时,问题就出现了。因为
initialize
方法被调用了两次,所以它无法识别变量只是被重新分配给了另一个类实例

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}"
当我在IRB中运行上述代码时,它会给我一个
票数2
(如预期的那样)。如何更改代码以使其识别覆盖

注意:我知道之前有人问过这个问题是关于目标C的,但问题的重新分配方面为问题添加了一个不同的元素。否则请告诉我

ObjectSpace.each_object(Ticket).count
将为您提供内存中当前对象的计数。在IRB中进行测试时,我发现它遇到了您描述的问题,即使您为变量指定了一个新的对象,对象仍会保留在内存中。从技术上讲,对象仍然存在,即使您为变量“a”指定了一个新实例

看这篇文章:答案中有很多关于你正在尝试做什么的信息

将为您提供内存中当前对象的计数。在IRB中进行测试时,我发现它遇到了您描述的问题,即使您为变量指定了一个新的对象,对象仍会保留在内存中。从技术上讲,对象仍然存在,即使您为变量“a”指定了一个新实例


请参阅本文:答案中有大量关于您正在尝试执行的操作的信息。

在现实世界中,您不会计算内存中的实例,而是询问数据库中存在多少实例。你需要从数据库的角度来思考

使用
a
重复包含票据实例是错误的。您应该使用数组、散列或集合来维护列表,然后询问容器存在多少:

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}"
require'set'
班票
属性存取器:价格
属性读取器:事件,地点
@@票=新票
def初始化(活动、场地)
@事件=事件
@地点

@@票证在现实世界中,您不会计算内存中的实例,而是询问数据库中存在多少实例。你需要从数据库的角度来思考

使用
a
重复包含票据实例是错误的。您应该使用数组、散列或集合来维护列表,然后询问容器存在多少:

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}"
require'set'
班票
属性存取器:价格
属性读取器:事件,地点
@@票=新票
def初始化(活动、场地)
@事件=事件
@地点
@@tickets如果您真的想计算
Ticket
类的实时实例(出于我无法理解的原因),@Beartech有一个正确的想法:

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
在调用之前进行垃圾收集是非常重要的。如果您对此持怀疑态度,请将
p ObjectSpace.each_object(self).to_a.size
作为
self.count_live_实例的第一行插入。它将打印
3

(还有一个方法。此方法返回如下哈希:
{:TOTAL=>56139,:T_ARRAY=>3139,:T_ICLASS=>32}
。不幸的是,键是“对象类型”;在它们之间找不到
:TICKET

如果您真的想计算
TICKET
类的活动实例(原因我无法理解),@Beartech的想法是正确的:

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
在调用之前进行垃圾收集是非常重要的。如果您对此持怀疑态度,请将
p ObjectSpace.each_object(self).to_a.size
作为
self.count_live_实例的第一行插入。它将打印
3

(还有一个方法。此方法返回如下哈希:
{:TOTAL=>56139,:T_ARRAY=>3139,,:T_ICLASS=>32}
。不幸的是,键是“对象类型”;在它们之间找不到
:TICKET

类Gs
def self.method1
代码。。。
结束
def self.method2
代码。。。
结束
def self.method3
代码。。。
结束
结束
Gs.new
p Gs.单例法计数

Gs.singleton\u methods.count
将打印
3
如果我们使用
self
关键字或 classname.method name..

classgs
def self.method1
代码。。。
结束
def self.method2
代码。。。
结束
def self.method3
代码。。。
结束
结束
Gs.new
p Gs.单例法计数

Gs.singleton\u methods.count
将打印
3
如果我们使用
self
关键字或
classname.method name..

您可以覆盖类对象的“新建”类方法并仅递增实例计数器一次。您可以覆盖类对象的“新建”类方法并仅递增实例计数器一次。如果重新分配
a
而没有首先销毁分配给
a
的票证,则上述代码仍返回计数3。在代码中重新分配之前,必须强制检查当前值。对于我们这些新用户来说,这是一个很有价值的教训:如果实现起来如此复杂,可能是因为没有简单的Ruby方法。i、 如您所指出的,还有其他最佳实践。只要存在对对象实例的引用,它就会保留在内存中。一旦删除了所有引用,Ruby将对实例进行垃圾收集,实例将不再存在。垃圾收集不会立即发生。如果你不能检索到它,它在内存中就没有任何意义。如果重新分配
a
而没有首先销毁分配给
a
的票证,则上述代码仍返回计数3。在代码中重新分配之前,必须强制检查当前值。对于我们这些新用户来说,这是一个很有价值的教训:如果实现起来如此复杂,可能有一个原因没有实现