Kernel#putc vs. $stdout#putc

G

Gordon Thiesfeld

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
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi:

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.


Arlen
 
G

Gordon Thiesfeld

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.

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
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi,

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top