class IO

Public Instance Methods

expect(pat,timeout=9999999) { |result| ... } click to toggle source

Reads from the IO until pattern pat matches or the timeout is over. It returns an array with the read buffer, followed by the matches. If a block is given, the result is yielded to the block and returns nil.

The optional timeout parameter defines, in seconds, the total time to wait for the pattern. If the timeout expires or eof is found, nil is returned or yielded. However, the buffer in a timeout session is kept for the next expect call. The default timeout is 9999999 seconds.

# File rake/lib/expect.rb, line 12
def expect(pat,timeout=9999999)
  buf = ''
  case pat
  when String
    e_pat = Regexp.new(Regexp.quote(pat))
  when Regexp
    e_pat = pat
  else
    raise TypeError, "unsupported pattern class: #{pattern.class}"
  end
  @unusedBuf ||= ''
  while true
    if not @unusedBuf.empty?
      c = @unusedBuf.slice!(0).chr
    elsif !IO.select([self],nil,nil,timeout) or eof? then
      result = nil
      @unusedBuf = buf
      break
    else
      c = getc.chr
    end
    buf << c
    if $expect_verbose
      STDOUT.print c
      STDOUT.flush
    end
    if mat=e_pat.match(buf) then
      result = [buf,*mat.to_a[1..-1]]
      break
    end
  end
  if block_given? then
    yield result
  else
    return result
  end
  nil
end
scanf(str) { |current_match| ... } click to toggle source

Scans the current string until the match is exhausted, yielding each match as it is encountered in the string. A block is not necessary though, as the results will simply be aggregated into the final array.

"123 456".block_scanf("%d")
# => [123, 456]

If a block is given, the value from that is returned from the yield is added to an output array.

"123 456".block_scanf("%d) do |digit,| # the ',' unpacks the Array
  digit + 100
end
# => [223, 556]

See Scanf for details on creating a format string.

You will need to require ‘scanf’ to use use #scanf.

# File rake/lib/scanf.rb, line 614
def scanf(str,&b) #:yield: current_match
  return block_scanf(str,&b) if b
  return [] unless str.size > 0

  start_position = pos rescue 0
  matched_so_far = 0
  source_buffer = ""
  result_buffer = []
  final_result = []

  fstr = Scanf::FormatString.new(str)

  loop do
    if eof || (tty? &&! fstr.match(source_buffer))
      final_result.concat(result_buffer)
      break
    end

    source_buffer << gets

    current_match = fstr.match(source_buffer)

    spec = fstr.last_spec_tried

    if spec.matched
      if spec.mid_match?
        result_buffer.replace(current_match)
        next
      end

    elsif (fstr.matched_count == fstr.spec_count - 1)
      if /\A\s*\z/.match(fstr.string_left)
        break if spec.count_space?
        result_buffer.replace(current_match)
        next
      end
    end

    final_result.concat(current_match)

    matched_so_far += source_buffer.size
    source_buffer.replace(fstr.string_left)
    matched_so_far -= source_buffer.size
    break if fstr.last_spec
    fstr.prune
  end
  seek(start_position + matched_so_far, IO::SEEK_SET) rescue Errno::ESPIPE
  soak_up_spaces if fstr.last_spec && fstr.space

  return final_result
end