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
Hi:
On Thu, Feb 21, 2008 at 4:44 AM, Gordon T. [email protected]
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
On Wed, Feb 20, 2008 at 7:54 PM, Arlen C. [email protected] 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
Hi,
On Fri, Feb 22, 2008 at 5:52 AM, Gordon T. [email protected]
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.