# Kernel#putc vs. $stdout#putc

**URL:** <https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688>\
**Category:** Ruby\
**Created:** [February 20, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688 "2008-02-20T18:45:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [February 20, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688/1 "2008-02-20T18:45:28Z")

</div>

I was under the impression that Kernel#putc was an alias, or wrapper  
around $stdout#putc, but I was mistaken. It turns out they’re both  
implemented separately in C, and both pass to $stdout.write. I’m  
trying to redefine putc in the Win32::Console::ANSI::IO object (in the  
win32console gem), so that it buffers ANSI escape sequences and passes  
them as a single unit. In order for this to work, I’ll have to  
redefine Kernel#putc to use Win32::Console::ANSI::IO#putc like this:

module Kernel

def putc(int)  
$stdout.putc(int)  
end

end

Does anyone see a reason why this would be a bad idea? If so, any  
other solutions?

Thanks,

Gordon

---

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [February 21, 2008, 2:55am UTC](https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688/2 "2008-02-21T02:55:04Z")

</div>

Hi:

On Thu, Feb 21, 2008 at 4:44 AM, Gordon T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I was under the impression that Kernel#putc was an alias, or wrapper  
> around $stdout#putc, but I was mistaken. It turns out they’re both  
> implemented separately in C, and both pass to $stdout.write.

Not quite:

static VALUE  
rb\_f\_putc(VALUE recv, VALUE ch)  
{  
return rb\_io\_putc(rb\_stdout, ch);  
}

Kernel#putc here passes to IO#putc anyway, which then (as you mention)  
uses  
IO#write.

> Gordon

Arlen

---

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [February 21, 2008, 7:52pm UTC](https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688/3 "2008-02-21T19:52:50Z")

</div>

On Wed, Feb 20, 2008 at 7:54 PM, Arlen C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

OK, here’s why I’m confused. In the code below, why isn’t the output  
of both of the putc methods 42?

class ChunkyIO \< IO

def putc(int)  
write ‘42’  
end

end

$stdout = ChunkyIO.new(1,‘w’)

putc ?K  
puts  
$stdout.putc ?K  
puts

#outputs  
K  
42

---

<div class="post-metadata">

**Author:** ![gordon321](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/d2c977/32.png) [@gordon321](https://www.ruby-forum.com/u/gordon321)\
**Post date:** [February 22, 2008, 12:21am UTC](https://www.ruby-forum.com/t/kernel-putc-vs-stdout-putc/129688/4 "2008-02-22T00:21:05Z")

</div>

Hi,

On Fri, Feb 22, 2008 at 5:52 AM, Gordon T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> OK, here’s why I’m confused. In the code below, why isn’t the output  
> of both of the putc methods 42?

Here’s the relevant code from io.c:

static VALUE  
rb\_io\_putc(VALUE io, VALUE ch)  
{  
char c = NUM2CHR(ch);

```
rb_io_write(io, rb_str_new(&c, 1));
return ch;

```

}

static VALUE  
rb\_f\_putc(VALUE recv, VALUE ch)  
{  
return rb\_io\_putc(rb\_stdout, ch);  
}

As you can see, rb\_f\_putc (Kernel.putc) is hard-wired to rb\_io\_putc  
(IO#putc) - but it’s directly hard-wired (I believe), not literally as  
“$stdout.putc” but rather going straight to the function as defined  
here.  
This means that the two functions are ‘identical’ in nature –  
Kernel.putcisn’t $stdout.putc, but rather will always call  
rb\_io\_write(rb\_stdout,  
rb\_str\_new(&ch, 1)), which is $stdout.write with a string of that one  
character.  
Hence, you actually would have to redefine both ($stdout.putc, by your  
ChunkyIO, _and_ Kernel.putc) – or redefine $stdout.write (in which case  
both functions will be affected) – in order to get the effect you want.

Cheers,  
Arlen.
