Class: IO

Inherits:
Object
  • Object
show all
Defined in:
lib/scanf.rb

Instance Method Summary collapse

Instance Method Details

#scanf(str, &b) ⇒ Object

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 IO#scanf.



614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
# File '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

  begin
    seek(start_position + matched_so_far, IO::SEEK_SET)
  rescue Errno::ESPIPE
  end

  soak_up_spaces if fstr.last_spec && fstr.space

  return final_result
end