1

我有一个 Ruby 类,它上面的每个方法都根据特定条件保留哈希数组的索引。

例如(代码自原始发布以来已被编辑

module Dronestream
  class Strike

    class << self

    ...
    def strike
      @strike ||= all
    end

    def all
      response['strike'] # returns an array of hashes, each individual strike
    end

    def in_country(country)
      strike.keep_if { |strike| strike['country'] == country }
      self
    end

    def in_town(town)
      strike.keep_if { |strike| strike['town'] == town }
      self
    end
    ...
  end
end  

这样,您可以执行Dronestream::Strike.in_country('Yemen'), 或Dronestream::Strike.in_town('Taizz'), 并且每个都返回一个数组。但我希望能够做到Dronestream::Strike.in_country('Yemen').in_town('Taizz'),并让它只返回也门那个小镇的罢工。

但截至目前,每个单独的方法都返回一个数组。我知道如果我让他们 return self,他们就会有我需要的方法。但是他们不会返回一个数组,例如,我不能调用它们,first或者each像我可以调用一个数组一样,我需要这样做。我试图做Strike < Array,但是,first是一个实例方法Array,而不是一个类方法。

我应该怎么办?

编辑

这是我的测试套件的一部分。按照下面的答案,测试单独通过,但随后失败。

describe Dronestream::Strike do

  let(:strike) { Dronestream::Strike }

  before :each do
    VCR.insert_cassette 'strike', :record => :new_episodes
    @strike = nil
  end

  after do
    VCR.eject_cassette
  end
  ...
  # passes when run by itself and when the whole file runs together
  describe '#country' do
    let(:country_name) { 'Yemen' }
    it 'takes a country and returns strikes from that country' do
      expect(strike.in_country(country_name).first['country']).to eq(country_name)
    end
  end

  # passes when run by itself, but fails when the whole file runs together
  describe '#in_town' do
    let(:town_name) { 'Wadi Abida' }
    it 'returns an array of strikes for a given town' do
      expect(strike.in_town(town_name).first['town'].include?(town_name)).to be_true 
    end
  end
  ...
end
4

1 回答 1

1

您可以覆盖method_missing来处理这个问题。
返回self您的in_countryorin_town方法。然后当调用first它时,将它传递给all数组进行处理。
代码可能是这样的:

module Dronestream
  class Strike

  class << self

  ...
  def all
    ...
  end

  def in_country(country)
    all.keep_if { |strike| strike['country'] == country }
    self
  end

  def in_town(town)
    all.keep_if { |strike| strike['town'] == town }
    self
  end
  ...

  def method_missing(name,*args,&block)
    return all.send(name.to_sym, *args, &block) if all.respond_to? name.to_sym
    super
  end
end
于 2013-06-06T06:15:53.427 回答