Search code examples
loopscrystal-lang

Crystal .cycle Recycle after finish looping


so in my case

def dynamic_data()
  data = [] of String
  # some data from db
  # data << db["somekey"].to_s
  return data
end

dynamic_data().cycle do |d|
  # some stuff
  puts d
end

My data reaches more than 500 row and will continue to grow and increase, how to make cycle finishing loop first, then reload new data again from function, or there is other method ? , thanks


Solution

  • how to make cycle finishing loop first

    There is no way to make Array#cycle finishing, since it is explicitly designed to run forever (unless break is called, but this is unlikely what you are looking for).

    If I properly understood your intent, you are trying to handle incoming portions of data. To do so, one needs more sophisticated handling, like:

    class DataHandler
      def initialize
        @data = []
      end
      def data()
        @data.tap(&:clear)
      end
      def data!(new_data)
        @data << new_data
      end
    end
    
    data_handler = DataHandler.new
    
    loop do
      break "empty data" if data_handler.data.empty?
      puts data_handler.data
    end
    

    Or, as pointed out in comments by Jonne Haß, using yield:

    def dynamic_data()
      data = []
      loop do
        data << new_data
        yield data.tap(&:clear) if data.size > 100
      end
    end
    
    dynamic_data do
      puts d
    end