0001-Adding-documentation-to-scanf.rb.patch

Gabe McArthur, 05/19/2011 09:06 AM

Download (12.1 KB)

View differences:

lib/scanf.rb
1
# scanf for Ruby
2
#
3
# $Release Version: 1.1.2 $
4
# $Revision$
5
# $Id$
6
# $Author$
7
#
8
# A product of the Austin Ruby Codefest (Austin, Texas, August 2002)
9

  
10 1
=begin
2
scanf for Ruby
3

  
4
$Release Version: 1.1.2 $
5
$Revision$
6
$Id$
7
$Author$
11 8

  
12
=scanf for Ruby
9
A product of the Austin Ruby Codefest (Austin, Texas, August 2002)
13 10

  
14
==Description
11
=scanf for ruby
15 12

  
16
scanf for Ruby is an implementation of the C function scanf(3),
17
modified as necessary for Ruby compatibility.
13
==description
18 14

  
19
The methods provided are String#scanf, IO#scanf, and
20
Kernel#scanf. Kernel#scanf is a wrapper around STDIN.scanf.  IO#scanf
21
can be used on any IO stream, including file handles and sockets.
15
scanf for ruby is an implementation of the c function scanf(3),
16
modified as necessary for ruby compatibility.
17

  
18
the methods provided are string#scanf, io#scanf, and
19
kernel#scanf. kernel#scanf is a wrapper around stdin.scanf.  io#scanf
20
can be used on any io stream, including file handles and sockets.
22 21
scanf can be called either with or without a block.
23 22

  
24
scanf for Ruby scans an input string or stream according to a
25
<b>format</b>, as described below ("Conversions"), and returns an
26
array of matches between the format and the input.  The format is
23
scanf for ruby scans an input string or stream according to a
24
<b>format</b>, as described below ("conversions"), and returns an
25
array of matches between the format and the input.  the format is
27 26
defined in a string, and is similar (though not identical) to the
28
formats used in Kernel#printf and Kernel#sprintf.
27
formats used in kernel#printf and kernel#sprintf.
29 28

  
30
The format may contain <b>conversion specifiers</b>, which tell scanf
29
the format may contain <b>conversion specifiers</b>, which tell scanf
31 30
what form (type) each particular matched substring should be converted
32 31
to (e.g., decimal integer, floating point number, literal string,
33
etc.)  The matches and conversions take place from left to right, and
32
etc.)  the matches and conversions take place from left to right, and
34 33
the conversions themselves are returned as an array.
35 34

  
36
The format string may also contain characters other than those in the
37
conversion specifiers.  White space (blanks, tabs, or newlines) in the
35
the format string may also contain characters other than those in the
36
conversion specifiers.  white space (blanks, tabs, or newlines) in the
38 37
format string matches any amount of white space, including none, in
39
the input.  Everything else matches only itself.
38
the input.  everything else matches only itself.
40 39

  
41
Scanning stops, and scanf returns, when any input character fails to
40
scanning stops, and scanf returns, when any input character fails to
42 41
match the specifications in the format string, or when input is
43 42
exhausted, or when everything in the format string has been
44
matched. All matches found up to the stopping point are returned in
43
matched. all matches found up to the stopping point are returned in
45 44
the return array (or yielded to the block, if a block was given).
46 45

  
47 46

  
48
==Basic usage
47
==basic usage
49 48

  
50 49
   require 'scanf.rb'
51 50

  
52
   # String#scanf and IO#scanf take a single argument (a format string)
53
   array = aString.scanf("%d%s")
54
   array = anIO.scanf("%d%s")
51
   # string#scanf and io#scanf take a single argument (a format string)
52
   array = astring.scanf("%d%s")
53
   array = anio.scanf("%d%s")
55 54

  
56
   # Kernel#scanf reads from STDIN
55
   # kernel#scanf reads from stdin
57 56
   array = scanf("%d%s")
58 57

  
59 58
==Block usage
......
211 210
in using any of the more complex and/or arcane character class
212 211
idioms.
213 212

  
213
==License and copyright
214

  
215
Copyright:: (c) 2002-2003 David Alan Black
216
License:: Distributed on the same licensing terms as Ruby itself
217

  
218
==Warranty disclaimer
219

  
220
This software is provided "as is" and without any express or implied
221
warranties, including, without limitation, the implied warranties of
222
merchantibility and fitness for a particular purpose.
223

  
224
==Credits and acknowledgements
225

  
226
scanf for Ruby was developed as the major activity of the Austin
227
Ruby Codefest (Austin, Texas, August 2002).
228

  
229
Principal author:: David Alan Black (mailto:dblack@superlink.net)
230
Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)
231
Project contributors:: Nolan Darilek, Jason Johnston
232

  
233
Thanks to Hal Fulton for hosting the Codefest.
234

  
235
Thanks to Matz for suggestions about the class design.
236

  
237
Thanks to Gavin Sinclair for some feedback on the documentation.
238

  
239
The text for parts of this document, especially the Description and
240
Conversions sections, above, were adapted from the Linux Programmer's
241
Manual manpage for scanf(3), dated 1995-11-01.
242

  
243
==Bugs and bug reports
244

  
245
scanf for Ruby is based on something of an amalgam of C scanf
246
implementations and documentation, rather than on a single canonical
247
description. Suggestions for features and behaviors which appear in
248
other scanfs, and would be meaningful in Ruby, are welcome, as are
249
reports of suspicious behaviors and/or bugs. (Please see "Credits and
250
acknowledgements", above, for email addresses.)
251

  
252
=end
253

  
214 254

  
255

  
256
#:stopdoc:
257
module Scanf
258

  
259
=begin
215 260
==Technical notes
216 261

  
217 262
===Rationale behind scanf for Ruby
......
258 303
when the FormatString object runs out of FormatSpecifiers, scanning
259 304
stops and results accumulated so far are returned in an array.
260 305

  
261
==License and copyright
262

  
263
Copyright:: (c) 2002-2003 David Alan Black
264
License:: Distributed on the same licensing terms as Ruby itself
265

  
266
==Warranty disclaimer
267

  
268
This software is provided "as is" and without any express or implied
269
warranties, including, without limitation, the implied warranties of
270
merchantibility and fitness for a particular purpose.
271

  
272
==Credits and acknowledgements
273

  
274
scanf for Ruby was developed as the major activity of the Austin
275
Ruby Codefest (Austin, Texas, August 2002).
276

  
277
Principal author:: David Alan Black (mailto:dblack@superlink.net)
278
Co-author:: Hal Fulton (mailto:hal9000@hypermetrics.com)
279
Project contributors:: Nolan Darilek, Jason Johnston
280

  
281
Thanks to Hal Fulton for hosting the Codefest.
282

  
283
Thanks to Matz for suggestions about the class design.
284

  
285
Thanks to Gavin Sinclair for some feedback on the documentation.
286

  
287
The text for parts of this document, especially the Description and
288
Conversions sections, above, were adapted from the Linux Programmer's
289
Manual manpage for scanf(3), dated 1995-11-01.
290

  
291
==Bugs and bug reports
292

  
293
scanf for Ruby is based on something of an amalgam of C scanf
294
implementations and documentation, rather than on a single canonical
295
description. Suggestions for features and behaviors which appear in
296
other scanfs, and would be meaningful in Ruby, are welcome, as are
297
reports of suspicious behaviors and/or bugs. (Please see "Credits and
298
acknowledgements", above, for email addresses.)
299

  
300 306
=end
301 307

  
302
module Scanf
303

  
304 308
  class FormatSpecifier
305 309

  
306 310
    attr_reader :re_string, :matched_string, :conversion, :matched
......
575 579
    end
576 580
  end
577 581
end
582
#:startdoc:
578 583

  
584
# When required, +scanf.rb+ adds the +scanf+ method to the +IO+
585
# class, for reading formatted strings from streams.
579 586
class IO
580 587

  
581
# The trick here is doing a match where you grab one *line*
582
# of input at a time.  The linebreak may or may not occur
583
# at the boundary where the string matches a format specifier.
584
# And if it does, some rule about whitespace may or may not
585
# be in effect...
586
#
587
# That's why this is much more elaborate than the string
588
# version.
589
#
590
# For each line:
591
# Match succeeds (non-emptily)
592
# and the last attempted spec/string sub-match succeeded:
593
#
594
#   could the last spec keep matching?
595
#     yes: save interim results and continue (next line)
596
#
597
# The last attempted spec/string did not match:
598
#
599
# are we on the next-to-last spec in the string?
600
#   yes:
601
#     is fmt_string.string_left all spaces?
602
#       yes: does current spec care about input space?
603
#         yes: fatal failure
604
#         no: save interim results and continue
605
#   no: continue  [this state could be analyzed further]
606
#
607
#
608

  
609
  def scanf(str,&b)
588
  #:stopdoc:
589
  # The trick here is doing a match where you grab one *line*
590
  # of input at a time.  The linebreak may or may not occur
591
  # at the boundary where the string matches a format specifier.
592
  # And if it does, some rule about whitespace may or may not
593
  # be in effect...
594
  #
595
  # That's why this is much more elaborate than the string
596
  # version.
597
  #
598
  # For each line:
599
  # Match succeeds (non-emptily)
600
  # and the last attempted spec/string sub-match succeeded:
601
  #
602
  #   could the last spec keep matching?
603
  #     yes: save interim results and continue (next line)
604
  #
605
  # The last attempted spec/string did not match:
606
  #
607
  # are we on the next-to-last spec in the string?
608
  #   yes:
609
  #     is fmt_string.string_left all spaces?
610
  #       yes: does current spec care about input space?
611
  #         yes: fatal failure
612
  #         no: save interim results and continue
613
  #   no: continue  [this state could be analyzed further]
614
  #
615
  #:startdoc:
616

  
617
  # Scans the current string until the match is exhausted,
618
  # yielding each match as it is encountered in the string.
619
  # A block is not necessary though, as the results will simply
620
  # be aggregated into the final array.
621
  #
622
  #   "123 456".block_scanf("%d")
623
  #   # => [123, 456]
624
  #
625
  # If a block is given, the value from that is returned from 
626
  # the yield is added to an output array.
627
  #
628
  #   "123 456".block_scanf("%d) do |digit,| # Requires a ',' to unpack the Array
629
  #     digit + 100
630
  #   end
631
  #   # => [223, 556]
632
  #
633
  def scanf(str,&b) #:yield: +current_match+
610 634
    return block_scanf(str,&b) if b
611 635
    return [] unless str.size > 0
612 636

  
......
684 708
  end
685 709
end
686 710

  
711
# String has two convenience methods for scanning the contents
712
# of a string object into an +Array+. The first is the standard
713
# +scanf+ function; the second is the +block_scanf+, which 
714
# yields a match to the given block, accumulating the output.
715
#
716
# Note that the String#scanf method will perform in the exact
717
# same way as String#block_scanf if passed a block.
718
#
687 719
class String
688 720

  
689
  def scanf(fstr,&b)
721
  # Scans the current string. If a block is given, it 
722
  # functions exactly like +block_scanf+.
723
  #
724
  #   arr = "123 456".scanf("%d%d")
725
  #   # => [123, 456]
726
  #
727
  #   require 'pp'
728
  #
729
  #   "this 123 read that 456 other".scanf("%s%d%s") {|m| pp m}
730
  #   
731
  #   # ["this", 123, "read"]
732
  #   # ["that", 456, "other"]
733
  #   # => [["this", 123, "read"], ["that", 456, "other"]] 
734
  #
735
  def scanf(fstr,&b) #:yield: +current_match+ if block_given?
690 736
    if b
691 737
      block_scanf(fstr,&b)
692 738
    else
......
700 746
    end
701 747
  end
702 748

  
703
  def block_scanf(fstr,&b)
749
  # Scans the current string until the match is exhausted,
750
  # yielding each match as it is encountered in the string.
751
  # A block is not necessary though, as the results will simply
752
  # be aggregated into the final array.
753
  #
754
  #   "123 456".block_scanf("%d")
755
  #   # => [123, 456]
756
  #
757
  # If a block is given, the value from that is returned from 
758
  # the yield is added to an output array.
759
  #
760
  #   "123 456".block_scanf("%d) do |digit,| # Requires a ',' to unpack the Array
761
  #     digit + 100
762
  #   end
763
  #   # => [223, 556]
764
  #
765
  def block_scanf(fstr,&b) #:yield: +current_match+
704 766
    fs = Scanf::FormatString.new(fstr)
705 767
    str = self.dup
706 768
    final = []
......
713 775
  end
714 776
end
715 777

  
716
module Kernel
778
# The Kernel#scanf method is private by default, but because +Kernel+
779
# is mixed in the +Object+ inheritance heirarchy, it is thus 
780
# available everywhere.
781
#
782
# It reads from +STDIN+.
783
#
784
module Kernel 
717 785
  private
718
  def scanf(fs,&b)
786
  # Queries +STDIN+ for input.
787
  def scanf(fs,&b) #:doc:
719 788
    STDIN.scanf(fs,&b)
720 789
  end
721 790
end
722
-