Wednesday, April 01, 2009

more with Call/cc and Fiber

継続版とファイバー版のmoreだけどファイバー版はうまく動かず

Call/cc

   1  PAGELEN = 10

   2  def puts_lines

   3    begin

   4      next_stop = PAGELEN

   5      ARGF.each_with_index do |line, i|

   6        print "#{i}:#{line}\r"

   7        next_stop += callcc { |c| more?(c) } if i >= next_stop

   8      end

   9    ensure

  10      system("stty -raw echo")

  11    end

  12  end

  13  

  14  def more?(c)

  15    print "\033[7m more? \033[m\033[7D"

  16    system("stty raw -echo")

  17    input = case STDIN.getc

  18    when ?q

  19      exit

  20    when ?n

  21      0

  22    when ?\s

  23      PAGELEN

  24    when ?r

  25      print "\033[0;0H\033[2J"

  26      ARGF.rewind

  27      0

  28    else

  29      0

  30    end

  31  =begin

  32    TODO next_stop = input; c.call; doesnt work.

  33  =end

  34    c.call(input)

  35  end

  36  

  37  puts_lines


Fiber

   1  PAGELEN = 10

   2  def puts_lines

   3    begin

   4      next_stop = PAGELEN

   5      f = Fiber.new do |arg|

   6        ARGF.each_with_index do |line, i|

   7          print "#{i}:#{line}\r"

   8          Fiber.yield(i) if i > arg

   9        end

  10      end

  11      n = f.resume(PAGELEN)

  12      more?(f, n)

  13    ensure

  14      system("stty -raw echo")

  15    end

  16  end

  17  

  18  def more?(f, cnt)

  19    loop do

  20      system("stty raw -echo")

  21      print "\033[7m more? \033[m\033[7D"

  22      input = case STDIN.getc

  23      when ?q

  24        exit

  25      when ?n

  26        0

  27      when ?\s

  28        PAGELEN

  29      when ?r

  30        print "\033[0;0H\033[2J"

  31        ARGF.rewind

  32        0

  33      else

  34        0

  35      end

  36      f.resume(input+cnt)

  37    end

  38  end

  39  

  40  puts_lines

No comments: