我正在研究类方法。
我正在尝试计算一个类的创建实例的数量。我可以通过在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中运行上面的代码时,它给了我一个Ticket count of 2
(如预期的那样)。如何更改代码以便识别覆盖?
注意:我知道之前已经针对目标C提出了这个问题,但问题的重新分配方面为问题添加了不同的元素。别的我知道。
答案 0 :(得分:3)
ObjectSpace.each_object(Ticket).count
将为您提供当前内存中对象的计数。在IRB中进行测试时,我发现它遇到了您描述的问题,即使您已为变量分配了新对象,对象也会在内存中保留。从技术上讲,即使您将新实例分配给变量“a”,该对象仍然存在。
请参阅此文章:Deleting an object in Ruby答案中有大量有关您要执行的操作的信息。
答案 1 :(得分:2)
在现实世界中,你不会计算内存中的实例,你会问一个数据库有多少存在。你需要从数据库的角度思考。
您使用a
重复包含Ticket实例是错误的。您应该使用Array,Hash或Set来维护列表,然后询问容器存在多少:
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}"
你可以通过添加从@@tickets
检索特定实例的方法来构建它,添加to_s
以便列出它们,但是,最后,你会想要使用真实的数据库。如果您的代码因任何原因而崩溃,您的整个故障单将会消失,这在现实生活中是不可接受的。
答案 2 :(得分:0)
如果确实想要计算Ticket
课程的实时实例(由于我无法理解的原因),@ Beechech有正确的想法:
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
在调用ObjectSpace#each_object
之前进行垃圾收集至关重要。如果您持怀疑态度,请插入p ObjectSpace.each_object(self).to_a.size
作为self.count_live_instances
的第一行。它将打印3
。
(还有一个方法ObjectSpace#count_objects
。此方法返回类似这样的哈希值:{:TOTAL=>56139,..., :T_ARRAY=>3139,..., :T_ICLASS=>32}
。不幸的是,键是“对象类型”;您将找不到:TICKET
其中。)
答案 3 :(得分:0)
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
Gs.singleton_methods.count
将打印3
如果我们使用self
关键字或
classname.method name ..