如何从哈希数组创建ruby类的实例?

时间:2014-10-17 08:03:00

标签: ruby oop collections enumerable

我有一个模块FDParser,它读取一个csv文件并返回一个很好的哈希数组,每个哈希都是这样的:

{
  :name_of_investment => "Zenith Birla",
  :type => "half-yearly interest",
  :folio_no => "52357",
  :principal_amount => "150000",
  :date_of_commencement => "14/05/2010",
  :period => "3 years",
  :rate_of_interest => "11.25"
}

现在我有一个Investment类接受上面的哈希作为输入,并根据我的需要转换每个属性。

class Investment
  attr_reader :name_of_investment, :type, :folio_no,
              :principal_amount, :date_of_commencement,
              :period, :rate_of_interest

  def initialize(hash_data)
    @name = hash_data[:name_of_investment]
    @type = hash_data[:type]
    @folio_no = hash_data[:folio_no]
    @initial_deposit = hash_data[:principal_amount]
    @started_on =hash_data[:date_of_commencement]
    @term = hash_data[:period]
    @rate_of_interest = hash_data[:rate_of_interest]
  end

  def type
    #-- custom transformation here
  end
end

我还有一个Porfolio类,我想用它来管理investment个对象的集合。以下是Portfolio类的内容:

class Portfolio
  include Enumerable
  attr_reader :investments

  def initialize(investments)
    @investments = investments
  end

  def each &block
    @investments.each do |investment|
      if block_given?
        block.call investment
      else
        yield investment
      end
    end
  end
end

现在我想要的是循环模块产生的investment_data动态创建投资类的实例,然后将这些实例作为输入发送到Portfolio

到目前为止,我试过了:

FDParser.investment_data.each_with_index do |data, index|
  "inv#{index+1}" = Investment.new(data)
end

但显然这不起作用,因为我得到一个字符串而不是一个对象实例。将一组实例发送到可以管理它们的可枚举集合类的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我不确定“作为输入发送到Portfolio”是什么意思;班级本身不接受“输入”。但是,如果您只是尝试将Investment个对象添加到@investments实例中的Portfolio实例变量中,请尝试以下操作:

portfolio = Portfolio.new([])

FDParser.investment_data.each do |data|
  portfolio.investments << Investment.new(data)
end

请注意,数组文字[]portfolio.investments的返回值指向此处的自相同Array对象。这意味着你可以等效地做到这一点,这可以说是更清楚一点:

investments = []

FDParser.investment_data.each do |data|
  investments << Investment.new(data)
end

Portfolio.new(investments)

如果您想玩一些高尔夫码,如果您使用map,它会进一步缩小。

investments = FDParser.investment_data.map {|data| Investment.new(data) }

Portfolio.new(investments)

我认为这比前一个选项更难阅读。