Discarding putc But Not puts

Hello,

I'm working with a third-party library that calls both putc and puts in a certain method. I'd like to discard what is written with putc for the duration of the method while keeping anything written to puts. Given that the method lets you hook in your own code at its start and end, how do I do this?

I've tried various approaches including replacing $stdout with a custom class, and opening $stdout and rewriting putc -- but I haven't quite succeeded.

For example, here's some code that doesn't work:

   class << $stdout
     alias :original_putc :putc
     def putc(obj)
     end
   end

>> putc 'b'
=> "b" # I was hoping for no output

And some more non-working code:

   class MyIO < StringIO
     def putc(obj)
     end
   end

   # In hook called at start of target method
   $original_stdout = $stdout
   $stdout = MyIO.new

   # In hook called at end of target method
   $stdout = $original_stdout

Result: both putc and puts appear to be discarded.

Could anyone please show me the light?

Thanks in advance,
Andy Stewart

···

-------
http://airbladesoftware.com

What about

def putc(obj)
end

puts "Hello"
putc "W"

Did I miss something?

···

--
Posted via http://www.ruby-forum.com/.

Running the following code may cast some light on your problem.

<code>
class << $stdout
   def putc(obj)
      puts "1 called"
   end
end
class << STDOUT
   def putc(obj)
      puts "2 called"
   end
end
module Kernel
   def putc(obj)
      puts "3 called"
   end
end

putc 'b'
</code>

Regards, Morton

···

On Oct 2, 2007, at 7:02 AM, Andrew Stewart wrote:

I'm working with a third-party library that calls both putc and puts in a certain method. I'd like to discard what is written with putc for the duration of the method while keeping anything written to puts. Given that the method lets you hook in your own code at its start and end, how do I do this?

I've tried various approaches including replacing $stdout with a custom class, and opening $stdout and rewriting putc -- but I haven't quite succeeded.

For example, here's some code that doesn't work:

  class << $stdout
    alias :original_putc :putc
    def putc(obj)
    end
  end

>> putc 'b'
=> "b" # I was hoping for no output

Could anyone please show me the light?

Hi,

>> putc 'b'
=> "b" # I was hoping for no output

Since I think other people satisfactorily answered the rest, note here
that "b" is a return value, and that a normal putc would look like this
on a console:

irb(main):001:0> putc 'b'
b=> "b"
irb(main):002:0>

So it was successful here. :slight_smile:

Arlen

···

On Tue, 2007-10-02 at 20:02 +0900, Andrew Stewart wrote:

Lars Ticot wrote:

What about

def putc(obj)
end

puts "Hello"
putc "W"

Did I miss something?

Yep, switching it back to normal.

Andrew Stewart wrote:

Could anyone please show me the light?

Try this:

putc 65
puts 65

def func
  alias orig_putc putc

  def putc(*args)
  end

  putc 66
  puts 66

  alias putc orig_putc
end

func

putc 67
puts 67

--output:--
A65
66
C67

···

--
Posted via http://www.ruby-forum.com/\.

Thanks, Morton, that's a good, methodical way to determine what's being called. Most helpful.

Regards,
Andy Stewart

···

On 2 Oct 2007, at 14:29, Morton Goldberg wrote:

Running the following code may cast some light on your problem.

<code>
class << $stdout
  def putc(obj)
     puts "1 called"
  end
end
class << STDOUT
  def putc(obj)
     puts "2 called"
  end
end
module Kernel
  def putc(obj)
     puts "3 called"
  end
end

putc 'b'
</code>

-------

7stud -- wrote:

Did I miss something?

Yep, switching it back to normal.

Oooops! :wink:

···

--
Posted via http://www.ruby-forum.com/\.

7stud -- wrote:

  def putc(*args)
  end

Hmmm...I guess you don't need the *args--apparently putc can only take
one arg.

···

--
Posted via http://www.ruby-forum.com/\.

Aliasing back again worked -- thanks.

It produces a warning ("discarding old putc") when it encounters the second alias, at the end of the target method. But I can live with that. Maybe undefining putc first would stop the warning but it's not immediately obvious to me how to do that.

Thanks for your help. I greatly appreciate it.

Regards,
Andy Stewart

···

On 2 Oct 2007, at 13:36, 7stud -- wrote:

Try this:

def func
  alias orig_putc putc

  def putc(*args)
  end

  putc 66
  puts 66

  alias putc orig_putc
end

-------

Andrew Stewart wrote:

  alias putc orig_putc
end

Aliasing back again worked -- thanks.

It produces a warning ("discarding old putc") when it encounters the
second alias, at the end of the target method. But I can live with
that.

I think the warning is saying, "Hey, there won't be any reference to the
putc def inside func if you do that last alias. Well, how about using
another alias to save the putc def in?

  ...
  alias garbage putc
  alias putc orig_putc
end

···

On 2 Oct 2007, at 13:36, 7stud -- wrote:

--
Posted via http://www.ruby-forum.com/\.

Ah, I see. Adding another alias does indeed obviate the warning. Thanks for the insight.

Regards,
Andy Stewart

···

On 2 Oct 2007, at 16:54, 7stud -- wrote:

Andrew Stewart wrote:

On 2 Oct 2007, at 13:36, 7stud -- wrote:

  alias putc orig_putc
end

Aliasing back again worked -- thanks.

It produces a warning ("discarding old putc") when it encounters the
second alias, at the end of the target method. But I can live with
that.

I think the warning is saying, "Hey, there won't be any reference to the
putc def inside func if you do that last alias. Well, how about using
another alias to save the putc def in?

  ...
  alias garbage putc
  alias putc orig_putc
end

-------