# IO should provide #each\_char and #chars

**URL:** <https://www.ruby-forum.com/t/io-should-provide-each-char-and-chars/131915>\
**Category:** Development\
**Created:** [March 14, 2008, 11:01am UTC](https://www.ruby-forum.com/t/io-should-provide-each-char-and-chars/131915 "2008-03-14T11:01:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yugui](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/ac91a4/32.png) [@Yugui](https://www.ruby-forum.com/u/Yugui)\
**Post date:** [March 14, 2008, 11:01am UTC](https://www.ruby-forum.com/t/io-should-provide-each-char-and-chars/131915/1 "2008-03-14T11:01:59Z")

</div>

Yuguie$B$G$9!#e(B

IOe$B$K$O%P%$%H%9%H%j!\<%`$@$1$G$O$J$/J8;z%9%H%j!<%`$H$7$F$N5!G=e(B  
e$B$b4|BT$5$l$F$$$k$H;W$&$N$G$9$,!“e(B  
IO#each\_chare$B$de(BIO#charse$B$,$”$j$^$;$s!#e(B

e$B%P%C%U%!$KFO$$$F$$$J$$%P%$%H$N$;$$$GIT40A4$JJ8;z$,=P8=$9$k2De(B  
e$BG=@-$r9M$($?$N$+$H$b;W$$$^$7$?$,!“e(Bgetce$B$,$”$k$J$ie(B  
each\_chare$B$b$"$k$Y$-$G$O$J$$$G$7$g$&$+!#e(B

e$B$H$j$"$($:!"e(Bgetce$B$r%Y!\<%9$K=q$$$F$\_$^$7$?!#e(B

–  
Yugui  
removed\_email\_address@domain.invalid

> **[IDM --I divide me](http://idm.s9.xrea.com)**
>
> àlTCgÁĂà́B«¯ꐫáQ¾Ƃ©ALXg³¾Ƃ©Aw¾Ƃ©A₨¢¬à¾Ƃ©AǗlɂƂÁĐg߂Ȃà̂ðW߂Ă݂܂µ½B

# Index: io.c

— io.c (revision 15781)  
+++ io.c (working copy)  
@@ -2226,8 +2226,79 @@  
return io;  
}

+static VALUE  
+io\_getc(rb\_io\_t \*fptr, rb\_encoding \*enc)  
+{

- int r, n;
- VALUE str;
- 
- if (io\_fillbuf(fptr) \< 0) {
- return Qnil;
- }
- r = rb\_enc\_precise\_mbclen(fptr-\>rbuf+fptr-\>rbuf\_off, fptr-\>rbuf  
+fptr-\>rbuf\_off+fptr-\>rbuf\_len, enc);
- if (MBCLEN\_CHARFOUND\_P(r) &&
- 

```
   (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf_len) {

```

- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, n);
- fptr-\>rbuf\_off += n;
- fptr-\>rbuf\_len -= n;
- }
- else if (MBCLEN\_NEEDMORE\_P(r)) {
- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, fptr-\>rbuf\_len);
- 

```
   fptr->rbuf_len = 0;

```

- 

```
 getc_needmore:

```

- 

```
   if (io_fillbuf(fptr) != -1) {

```

- 

```
       rb_str_cat(str, fptr->rbuf+fptr->rbuf_off, 1);

```

- 

```
       fptr->rbuf_off++;

```

- 

```
       fptr->rbuf_len--;

```

- 

```
       r = rb_enc_precise_mbclen(RSTRING_PTR(str),

```

RSTRING\_PTR(str)+RSTRING\_LEN(str), enc);

- 

```
       if (MBCLEN_NEEDMORE_P(r)) {

```

- 

```
           goto getc_needmore;

```

- 

```
       }

```

- 

```
   }

```

- }
- else {
- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, 1);
- fptr-\>rbuf\_off++;
- fptr-\>rbuf\_len–;
- }
- return io\_enc\_str(str, fptr);  
+}
- /\*
  - call-seq:

- 
  - 

```
ios.each_char {|c| block } => ios

```

- 
  - 

- 
  - Calls the given block once for each character in _ios_,

- 
  - passing the character as an argument. The stream must be opened for

- 
  - reading or an `IOError` will be raised.

- 
  - 

- 
  - 

```
f = File.new("testfile")

```

- 
  - 

```
f.each_char {|c| print c, ' ' } #=> #<File:testfile>

```

- \*/
- 

+static VALUE  
+rb\_io\_each\_char(VALUE io)  
+{

- rb\_io\_t \*fptr;
- rb\_encoding \*enc;
- VALUE c;
- 
- RETURN\_ENUMERATOR(io, 0, 0);
- GetOpenFile(io, fptr);
- rb\_io\_check\_readable(fptr);
- 
- enc = io\_input\_encoding(fptr);
- READ\_CHECK(fptr);
- while (!NIL\_P(c = io\_getc(fptr, enc))) {
- 

```
   rb_yield(c);

```

- }
- return io;  
+}
- 
- 
- 

+/\*

- 
  - call-seq:
  - 

```
str.lines(sep=$/) => anEnumerator

```

  - 

```
str.lines(limit) => anEnumerator

```

  - 

```
str.lines(sep, limit) => anEnumerator

```

@@ -2239,9 +2310,9 @@  
\*/

static VALUE  
-rb\_io\_lines(int argc, VALUE \*argv, VALUE str)  
+rb\_io\_lines(int argc, VALUE \*argv, VALUE io)  
{

- return rb\_enumeratorize(str, ID2SYM(rb\_intern(“each\_line”)),  
argc, argv);

- return rb\_enumeratorize(io, ID2SYM(rb\_intern(“each\_line”)), argc,  
argv);  
}

/\*  
@@ -2254,13 +2325,31 @@  
\*/

static VALUE  
-rb\_io\_bytes(VALUE str)  
+rb\_io\_bytes(VALUE io)  
{

- return rb\_enumeratorize(str, ID2SYM(rb\_intern(“each\_byte”)), 0, 0);

- return rb\_enumeratorize(io, ID2SYM(rb\_intern(“each\_byte”)), 0, 0);  
}

/\*

- call-seq:

- 
  - 

```
ios.chars => anEnumerator

```

- 
  - 

- 
  - Returns an enumerator that gives each character in _ios_.

- 
  - The stream must be opened for reading or an `IOError`

- 
  - will be raised.

- 
  - 

- 
  - 

```
f = File.new("testfile)

```

- 
  - 

```
f.chars.each {|c| print c, ' ' }

```

- \*/
- 

+static VALUE  
+rb\_io\_chars(VALUE io)  
+{

- return rb\_enumeratorize(io, ID2SYM(rb\_intern(“each\_char”)), 0, 0);  
+}
- 

+/\*

- 
  - call-seq:

  - 

```
ios.getc => fixnum or nil

```

  - 
  - Reads a one-character string from _ios_. Returns  
@@ -2284,38 +2373,8 @@

- if (io\_fillbuf(fptr) \< 0) {
- return Qnil;
- }
- r = rb\_enc\_precise\_mbclen(fptr-\>rbuf+fptr-\>rbuf\_off, fptr-\>rbuf  
+fptr-\>rbuf\_off+fptr-\>rbuf\_len, enc);
- if (MBCLEN\_CHARFOUND\_P(r) &&
- 

```
   (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf_len) {

```

- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, n);
- fptr-\>rbuf\_off += n;
- fptr-\>rbuf\_len -= n;
- }
- else if (MBCLEN\_NEEDMORE\_P(r)) {
- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, fptr-\>rbuf\_len);
- 

```
   fptr->rbuf_len = 0;

```

- 

```
 getc_needmore:

```

- 

```
   if (io_fillbuf(fptr) != -1) {

```

- 

```
       rb_str_cat(str, fptr->rbuf+fptr->rbuf_off, 1);

```

- 

```
       fptr->rbuf_off++;

```

- 

```
       fptr->rbuf_len--;

```

- 

```
       r = rb_enc_precise_mbclen(RSTRING_PTR(str),

```

RSTRING\_PTR(str)+RSTRING\_LEN(str), enc);

- 

```
       if (MBCLEN_NEEDMORE_P(r)) {

```

- 

```
           goto getc_needmore;

```

- 

```
       }

```

- 

```
   }

```

- }
- else {
- str = rb\_str\_new(fptr-\>rbuf+fptr-\>rbuf\_off, 1);
- fptr-\>rbuf\_off++;
- fptr-\>rbuf\_len–;
- }
- return io\_enc\_str(str, fptr);

- return io\_getc(fptr, enc);  
}

- int  
rb\_getc(FILE \*f)  
{  
@@ -6477,6 +6536,17 @@  
}

- RETURN\_ENUMERATOR(argf, 0, 0);
- for (;😉 {
- if (!next\_argv()) return Qnil;
- rb\_block\_call(current\_file, rb\_intern(“each\_char”), 0, 0, rb\_yield,  
0);
- next\_p = 1;
- }  
+}
- 

+static VALUE  
argf\_filename(VALUE argf)  
{  
next\_argv();  
@@ -6773,8 +6843,10 @@  
rb\_define\_method(rb\_cIO, “each”, rb\_io\_each\_line, -1);  
rb\_define\_method(rb\_cIO, “each\_line”, rb\_io\_each\_line, -1);  
rb\_define\_method(rb\_cIO, “each\_byte”, rb\_io\_each\_byte, 0);

- rb\_define\_method(rb\_cIO, “each\_char”, rb\_io\_each\_char, 0);  
rb\_define\_method(rb\_cIO, “lines”, rb\_io\_lines, -1);  
rb\_define\_method(rb\_cIO, “bytes”, rb\_io\_bytes, 0);

- rb\_define\_method(rb\_cIO, “chars”, rb\_io\_chars, 0);

- rb\_define\_method(rb\_cARGF, “each\_char”, argf\_each\_char, 0);

---

<div class="post-metadata">

**Author:** ![Yugui](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/ac91a4/32.png) [@Yugui](https://www.ruby-forum.com/u/Yugui)\
**Post date:** [March 15, 2008, 1:31pm UTC](https://www.ruby-forum.com/t/io-should-provide-each-char-and-chars/131915/2 "2008-03-15T13:31:29Z")

</div>

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:34052] IO should provide #each\_char and  
#chars”  
on Fri, 14 Mar 2008 19:00:39 +0900, Yugui [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|IOe$B$K$O%P%$%H%9%H%j!\<%`$@$1$G$O$J$/J8;z%9%H%j!<%`$H$7$F$N5!G=e(B  
|e$B$b4|BT$5$l$F$$$k$H;W$&$N$G$9$,!“e(B  
|IO#each\_chare$B$de(BIO#charse$B$,$”$j$^$;$s!#e(B  
|  
|e$B%P%C%U%!$KFO$$$F$$$J$$%P%$%H$N$;$$$GIT40A4$JJ8;z$,=P8=$9$k2De(B  
|e$BG=@-$r9M$($?$N$+$H$b;W$$$^$7$?$,!“e(Bgetce$B$,$”$k$J$ie(B  
|each\_chare$B$b$“$k$Y$-$G$O$J$$$G$7$g$&$+!#e(B  
|  
|e$B$H$j$”$($:!"e(Bgetce$B$r%Y!\<%9$K=q$$$F$\_$^$7$?!#e(B

(e$B%3%_%C%H8"$,Mh$?$ie(B)e$B%3%_%C%H$7$F$/$@$5$$!#e(B
