Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
存储Ruby对象的集合_Ruby_Oop - Fatal编程技术网

存储Ruby对象的集合

存储Ruby对象的集合,ruby,oop,Ruby,Oop,我试图在另一个对象中存储对象集合。我完成了如下的编码挑战 首先是单个对象: class Account attr_reader :user_name, :credit, :debit def initialize(user_name) @user_name = user_name @credit = 0 @debit = 0 end end 接下来是收藏: class AccountsCollection attr_reader :accounts

我试图在另一个对象中存储对象集合。我完成了如下的编码挑战

首先是单个对象:

class Account
  attr_reader :user_name, :credit, :debit

  def initialize(user_name)
    @user_name = user_name
    @credit = 0
    @debit = 0
  end
end
接下来是收藏:

class AccountsCollection
  attr_reader :accounts

  def initialize
    @accounts = []
  end

  def add_new_account(user)
    accounts << Account.new(user)
  end

  ...
end

但是我必须调用
accounts.accounts
来获得account对象的列表。这奇怪吗?有人能告诉我怎么才能做得更好吗?

真的,除了命名看起来很尴尬之外,我觉得它还不错。如果是我,我会有这样的名字,这样使用它看起来很好

class AccountsCollection
  def initialize
    @accounts = []
  end

  def add(user)
    accounts << Account.new(user)
  end

  def to_a
    @accounts
  end
end
类帐户集合
def初始化
@账户=[]
结束
def添加(用户)
帐目#
accounts.add('A')
账户。添加('B')
accounts.add('C')
帐目
=>[
#,
#,
#
]

依我看,你的代码的味道很简单,它是一个集合,但我不能把它当作一个集合。例如,如果我想要所有拥有10个以上信用的账户,我就必须从集合中取出账户数组:

accounts.accounts.select { |account| account.credit > 10 }
而您真正想要的是能够查询集合中的信息:

accounts.select { |account| account.credit > 10 }
要使您的收藏更像一个收藏,您需要包括以下内容,这要求您实现
每个
方法:

class AccountsCollection
  include Enumerable

  def initialize
    @accounts = []
  end

  def add(user_name)
    @accounts << Account.new(user_name)

    self # return self because that's more in-line with other collections
  end

  def each
    return to_enum(__method__) { @accounts.size } unless block_given?

    @accounts.each { |account| yield account }
  end
end
这(默认情况下)将通过
each
方法创建一个新数组,这样就不会直接修改数组(尽管仍然可以修改内容)


现在,事情开始感觉和气味好多了,只需很少的工作,其他试图使用您的
AccountsCollection
的人会非常高兴,因为他们可以使用他们习惯的所有搜索和遍历方法。

“不得不调用accounts.accounts来获取列表”–嗯,该列表应封装在
AccountsCollection
中。为什么你需要/想要直接访问它?这里的问题是为什么你首先需要一个新的类?对于当前的实现,我将只使用普通数组。如果有一些更重要的功能,它将引导你找到一个更好的名字。无论如何,如果出于任何原因,您坚持使用
accountscolection
,只需将
accounts
方法重命名为
为\u a
@ndn owh,这是因为我遗漏了一些属性。还有其他属性,如贷方、借方和余额。对不起,我应该把它包括在里面。我遗漏了accountscollection的另一个方法,即创建或初始化get_user(name)| | add_new_account(name)。可以说,
show
可能不是这里的最佳名称。假设您想从这个集合中提取一个数组,惯用的ruby方法是使用
to_a
方法。更新,谢谢您可能希望
dup
阵列以防止直接修改。谢谢简单的线路!这很有帮助。=)
accounts.accounts.select { |account| account.credit > 10 }
accounts.select { |account| account.credit > 10 }
class AccountsCollection
  include Enumerable

  def initialize
    @accounts = []
  end

  def add(user_name)
    @accounts << Account.new(user_name)

    self # return self because that's more in-line with other collections
  end

  def each
    return to_enum(__method__) { @accounts.size } unless block_given?

    @accounts.each { |account| yield account }
  end
end
accounts = AccountsCollection.new
accounts.add('A').add('B').add('C')

accounts.each.with_index do |account, index|
  # I changed the attr_reader in Account to attr_accessor just to illustrate
  account.credit = index * 10
end

accounts.select { |account| account.credit > 10 }
# => [#<Account:0x00007fe50d894208 @user_name="C", @credit=20, @debit=0>]
accounts.to_a
# => [#<Account:0x00007f879a094538 @user_name="A", @credit=0, @debit=0>,
#     #<Account:0x00007f879a094308 @user_name="B", @credit=10, @debit=0>,
#     #<Account:0x00007f879a0968b0 @user_name="C", @credit=20, @debit=0>]
accounts.to_a[1].debit = 15
accounts.to_a << 'not an account'

accounts.to_a
# => [#<Account:0x00007fb51c08a9c0 @user_name="A", @credit=0, @debit=0>,
#     #<Account:0x00007fb51c08a6a0 @user_name="B", @credit=10, @debit=15>,
#     #<Account:0x00007fb51c08a588 @user_name="C", @credit=20, @debit=0>]
def to_a
  @accounts.dup
end