Ruby:对象/类数组

15

我不是Ruby专家,这给了我一些麻烦。但如果我想要在Ruby中创建一个对象/类的数组,我该怎么做?如何初始化/声明它?提前感谢您的帮助。

这是我的类,我想创建它的一个数组:

class DVD
  attr_accessor :title, :category, :runTime, :year, :price

  def initialize()
    @title = title
    @category = category
    @runTime = runTime
    @year = year
    @price = price
  end
end

由于它在一个类中,我想让类中的其他方法可以访问它,所以我尝试了:@@movies = Array DVD.new但很快发现那行不通。 - Chris Cruz
你的意思是想创建一个包含类实例的数组吗? - Marcelo De Polli
请检查这个链接是否有所帮助:https://dev59.com/0Gw15IYBdhLWcg3w1vSB - Marcelo De Polli
3个回答

20

Ruby是一种鸭子类型(动态类型)的编程语言,几乎所有东西都是对象,因此您可以将任何对象添加到数组中。例如:

[DVD.new, DVD.new]

将创建一个包含2个DVD的数组。

a = []
a << DVD.new

将DVD添加到数组中。请查看Ruby API以获取完整的数组函数列表

顺便说一下,如果你想在DVD类中保留所有DVD实例的列表,可以使用类变量,并在创建新DVD对象时将其添加到该数组中。

class DVD
  @@array = Array.new
  attr_accessor :title, :category, :runTime, :year, :price 

  def self.all_instances
    @@array
  end

  def initialize()
    @title = title
    @category = category
    @runTime = runTime
    @year = year
    @price = price
    @@array << self
  end
end

现在,如果你这样做

DVD.new

您可以获取到目前为止您创建的所有DVD列表:

DVD.all_instances

1
并不是几乎所有的东西都是对象,而是 所有的东西都是对象。另外,在一般情况下,应该优先使用类实例变量而非类变量。 - Andrew Marshall
1
除了真正的块是对象之外:def f &block; block; end; f {}。它返回,嗯,一个对象 - Andrew Marshall
1
@AndrewMarshall 是的,就像它们被转换为过程一样,但当你必须为它产生收益时,它不是一个对象 :) 因此并非所有东西,但几乎所有东西都是对象。 - rik.vanmechelen

9

two_DVD = Array.new(2){DVD.new}


2
我第一次尝试使用 Array.new(2, DVD.new) 的时候,发现它创建了两个相同对象的副本。后来,我看到了你的答案 "Array.new(2){DVD.new}",发现它可以创建 2 个独立的对象,这正是我所需要的。非常感谢! - JasonArg123

7
为了在Ruby中创建对象数组:
  1. Create the array and bind it to a name:

    array = []
    
  2. Add your objects to it:

    array << DVD.new << DVD.new
    
你可以随时将任何对象添加到数组中。
如果您希望访问DVD类的每个实例,则可以依赖于ObjectSpace
class << DVD
  def all
    ObjectSpace.each_object(self).entries
  end
end

dvds = DVD.all

顺便说一下,实例变量没有被正确地初始化。

以下方法调用:

attr_accessor :title, :category, :run_time, :year, :price

自动创建attribute/attribute=实例方法,用于获取和设置实例变量的值。

initialize方法定义如下:

def initialize
  @title = title
  @category = category
  @run_time = run_time
  @year = year
  @price = price
end

设置实例变量,尽管不需要参数。实际上发生的是:

  1. 调用属性读取方法attribute
  2. 它读取未设置的变量
  3. 它返回nil
  4. nil成为变量的值

你想做的是将变量的值传递给initialize方法:

def initialize(title, category, run_time, year, price)
  # local variables shadow the reader methods

  @title = title
  @category = category
  @run_time = run_time
  @year = year
  @price = price
end

DVD.new 'Title', :action, 90, 2006, 19.99

此外,如果唯一必需的属性是DVD的标题,则可以按照以下方式进行操作:
def initialize(title, attributes = {})
  @title = title

  @category = attributes[:category]
  @run_time = attributes[:run_time]
  @year = attributes[:year]
  @price = attributes[:price]
end

DVD.new 'Second'
DVD.new 'Third', price: 29.99, year: 2011

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接