为什么with_progress做“Thread.new”?

时间:2009-09-10 16:30:36

标签: ruby

This code根据gem清单将gem安装到您的项目中。为什么需要为此生成线程?

module Gemifest
  class Installer
    def initialize(gem)
      @gem = gem
    end

    def perform!
      begin
        $stdout = StringIO.new('')
        $stderr = StringIO.new('')
        with_progress 'Installing ' + @gem.name do
          `#{@gem_command} install --no-ri --no-rdoc #{@gem.line}`
        end
      ensure
        $stderr = STDERR
        $stdout = STDOUT
      end
    end

    private

    def with_progress(label)
      STDERR.print label
      begin
        t = Thread.new do
          loop do
            STDERR.print('.')
            STDERR.flush
            sleep 0.8
          end
        end
        yield
        STDERR.puts ' done!' unless $?.exitstatus > 0
      rescue => e
        STDOUT.puts "Error:"
        STDOUT.puts e.message
      ensure
        t.kill
      end
    end
  end
end

1 个答案:

答案 0 :(得分:3)

如果您要移除Thread.new yield将在loop do ... end完成后执行(即从不)。

将循环放在一个单独的线程中的目的是它应该与块同时执行,然后在块完成后被杀死。