My .irbrc for console/irb

I recently discovered that I can create a .irbrc file to run setup for
my irb/console. I am in love.

My current .irbrc is:

require 'irb/completion'
require 'map_by_method'
require 'what_methods'
require 'pp'
IRB.conf[:AUTO_INDENT]=true

Explanation of the different libraries:
http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/

Does anyone any interesting things in their .irbrc file?

Nic

···

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

I haven't used it but Wirble(http://pablotron.org/software/wirble/\)
looks pretty cool.

Farrel

···

On 12/10/06, Dr Nic <drnicwilliams@gmail.com> wrote:

I recently discovered that I can create a .irbrc file to run setup for
my irb/console. I am in love.

My current .irbrc is:

require 'irb/completion'
require 'map_by_method'
require 'what_methods'
require 'pp'
IRB.conf[:AUTO_INDENT]=true

Explanation of the different libraries:
http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/

Does anyone any interesting things in their .irbrc file?

Nic

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

Sure, see

http://blog.nicksieger.com/articles/2006/04/23/tweaking-irb

Cheers,
/Nick

···

On 10/12/06, Dr Nic <drnicwilliams@gmail.com> wrote:

I recently discovered that I can create a .irbrc file to run setup for
my irb/console. I am in love.

Does anyone any interesting things in their .irbrc file?

Mine is rather large and in flux right now but I will post a few
nuggets from it bellow:

require 'rubygems'

# Very basic prelude of enhancements for Object
module ObjectEnhancer

  def clone!
    self.clone rescue self
  end

  def tap
    yield self
    self
  end

  def _
    yield if block_given?
    nil
  end

end

class Object
  include ObjectEnhancer
end

# Lazy loading prety print support
class Object
  def pp(*a, &b) # pass the block just-in-case this changes.
    require 'pp'
    pp(*a, &b)
  end
end

# Tab completion
require 'irb/completion'
IRB.conf[:USE_READLINE] = true

# Histories
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:EVAL_HISTORY] = 100

# Prompts
IRB.conf[:PROMPT][:CUSTOM] = {
    :PROMPT_N => ">> ",
    :PROMPT_I => ">> ",
    :PROMPT_S => nil,
    :PROMPT_C => " > ",
    :RETURN => "=> %s\n"
}

# Set default prompt
IRB.conf[:PROMPT_MODE] = :CUSTOM

# Simple ri integration
def ri(*names)
  system("ri #{names.map {|name| name.to_s}.join(" ")}")
end

# fresh irb. It uses an at_exit handler to yield it a block is given.
def reset_irb
  at_exit {exec($0)} # first registered is last to run
  at_exit {yield if block_given?}

  # From finalizer code in irb/ext/save-history.rb.. very ugly way to
do it :S.. who wants to rewrite irb?
  if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
    if hf = IRB.conf[:HISTORY_FILE]
      file = File.expand_path(hf)
    end
    file = IRB.rc_file("_history") unless file
    open(file, 'w') do |file|
      hist = IRB::HistorySavingAbility::HISTORY.to_a
      file.puts(hist[-num..-1] || hist)
    end
  end

  # Make irb give us a clean exit (up until our at_exit handler above)
  throw :IRB_EXIT, 0
end

# clear the screen.. with some self destruction :wink:
def clear
  eval "def clear; print #{`clear`.inspect} end"
  clear
end
private :clear

# Simple webserver (Loazy loading)
def serve_files(opts = {})
  require 'webrick'

  opts[:host] ||= Socket.gethostname
  opts[:dir] ||= Dir.pwd
  opts[:port] ||= opts[:dir].hash % 1000 + 10000
  opts[:log] ||= Nop.new # hidden and simple.

  server = WEBrick::HTTPServer.new(
    :Host => opts[:host],
    :Port => opts[:port],
    :DocumentRoot => opts[:dir],
    :Logger => opts[:log]
  )

  trap("INT") {server.shutdown}

  puts "Serving \"#{opts[:dir]}\" at http://#{opts[:host]}:#{opts[:port]}/"
  server.start
  nil
rescue
  puts "Failed to start server! See $webrick_error for the exception."
  $webrick_error = $!
  nil
end
private :serve_files

# SSH support. Needs a lot of work still but it is nice to have.
# This was just a 5 min hack. Thanks goes to Jamis for the
# nice library.
# Note that you must sleep to have the event loop run.
def ssh_session(opts = {})
  puts "Note: You must 'sleep' in order for the event loop to run in
irb." if require 'net/ssh'

  dynamic_session_class = Class.new do
    @@default_opts = {
      :user => ENV['USER'] || ENV['USERNAME'],
      :port => 22
    }.freeze

    def initialize(opts = {}, aux = {})
      opts, opts[:host] = aux, opts unless Hash === opts
      opts = aux.merge opts
      opts = @@default_opts.merge opts

      @shutdown = false
      @queue =

      ready = false
      Thread.new {
        begin
          Net::SSH.start(opts[:host],
            :username => opts[:user],
            :password => opts[:password],
            :port => opts[:port]
          ) do |session|
            ready = true
            loop {
              break if self.shutdown?
              self.process(session)
              session.loop
              sleep 0.01
            }
          end
        rescue
          puts "Failed while running ssh session! See $ssh_error for
the exception."
          $ssh_error = $!
        ensure
          ready = true
        end
      }
      sleep 0 until ready
    end

    def shutdown?
      @shutdown
    end

    def shutdown
      @shutdown = true
    end

    def execute(&blk)
      raise "Session shutdown" if shutdown?
      @queue << blk
      nil
    end

    def process(session)
      while proc = @queue.pop
        proc.call(session)
      end
    end

    def forward_local(port, host, aux_port = port)
      execute {|session|
        session.forward.local('0.0.0.0', port, host, aux_port)
      }
    end
    alias outgoing forward_local

    def forward_remote(port, host, aux_port = port)
      execute {|session|
        session.forward.remote_to(port, host, aux_port)
      }
    end

    def shell
      require 'termios'
      puts "Note: You will need to interrupt 'sleep' when your shell
is done (usually ^C)."
      execute {|session|
        stdin_buffer = lambda do |enable|
          attrs = Termios::getattr($stdin)
          if enable
            attrs.c_lflag |= Termios::ICANON | Termios::ECHO
          else
            attrs.c_lflag &= ~(Termios::ICANON | Termios::ECHO)
          end
          Termios::setattr($stdin, Termios::TCSANOW, attrs)
        end

        begin
          stdin_buffer[false]

          shell = session.shell.open(:pty => true)

          loop do
            break unless shell.open?
            if IO.select([$stdin],nil,nil,0.01)
              data = $stdin.sysread(1)
              shell.send_data data
            end

            $stdout.print shell.stdout while shell.stdout?
            $stdout.flush
          end
        ensure
          stdin_buffer[true]
        end
      }
      sleep
    end
    alias incoming forward_remote

  end

  Object.const_set('DynamicSSHSession', dynamic_session_class) unless
Object.constants.include? 'DynamicSSHSession'

  dynamic_session_class.new(opts)
rescue
  puts "Failed to create an ssh session! See $ssh_error for the exception."
  $ssh_error = $!
end
private :ssh_session

# Like haskell's sequence. Really nice to have but recursive.
# I should change this it an iterative solution sometime.
# Recursion is usually not a problem for realistic inputs.
class Array
  def sequence(i = 0, *a)
    return [a] if i == size
    self[i].map {|x|
      sequence(i+1, *(a + ))
    }.inject() {|m, x| m + x}
  end
end

class Symbol
  def to_proc
    lambda {|*args| args.shift.__send__(self, *args)}
  end
end

# Modulized blank slate. Only removes current not future
# methods for simplicities sake.
module Blank
  def self.append_features(base)
    base.module_eval {
      instance_methods.each {|m| undef_method m unless m =~ /^__/}
    }
  end
end

# This is mostly a toy but it has been useful in a few cases
# where I needed to slowly build up a proc inside multiple
# calls
class It < Proc
  instance_methods.each {|m| undef_method m unless m =~ /^__/}

  def method_missing(*args, &blk)
    It.new {|x|
Proc.instance_method(:call).bind(self).call(x).send(*args, &blk)}
  end
end

def it
  if block_given?
    It.new
  else
    It.new {|x| x}
  end
end
private :it

That is about half of it. I've got more stuff like gray number stuf,
unbound method extensions, and some new meta-programming stuff but it
all needs a little more work first. I should also note that I wrap my
irbrc file with a begin rescue end. The rescue just prints the
presence of an error and then shoves $! into $irbrc_error. This is
nice for occasions when you might be trying out new 1.9 builds or use
rails (they don't correctly initialize IRB so it causes failed loads
of irbrc -- keeps the output a little cleaner).

I will probably do another clean-up before RubyConf so we can all
share .irbrc's ;-). I'll probably end up removing more things then I
add (i.e. I really don't use Symbol#to_proc that much).

One last thing, I was wondering if anyone would be interested in a
series of gems that act as automatic irb plugins? it might be fun to
gemify some of these things.

Brian.

···

On 10/12/06, Dr Nic <drnicwilliams@gmail.com> wrote:

I recently discovered that I can create a .irbrc file to run setup for
my irb/console. I am in love.

My current .irbrc is:

require 'irb/completion'
require 'map_by_method'
require 'what_methods'
require 'pp'
IRB.conf[:AUTO_INDENT]=true

Explanation of the different libraries:
http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/

Does anyone any interesting things in their .irbrc file?

### I have these to help keep output manageable:

class Array
  alias :__orig_inspect :inspect

  def inspect
    (length > 20) ? "[ ... #{length} elements ... ]" : __orig_inspect
  end
end

class Hash
  alias :__orig_inspect :inspect

  def inspect
    (length > 20) ? "{ ... #{length} keys ... }" : __orig_inspect
  end
end

#### This for history (I believe I got it from Rubygarden):

HISTFILE = "~/.irb.hist"
MAXHISTSIZE = 100

begin
  if defined? Readline::HISTORY
    histfile = File::expand_path( HISTFILE )
    if File::exists?( histfile )
      lines = IO::readlines( histfile ).collect {|line| line.chomp}
      puts "Read %d saved history commands from %s." %
        [ lines.nitems, histfile ] if $DEBUG || $VERBOSE
      Readline::HISTORY.push( *lines )
    else
      puts "History file '%s' was empty or non-existant." %
        histfile if $DEBUG || $VERBOSE
    end

    Kernel::at_exit {
      lines = Readline::HISTORY.to_a.reverse.uniq.reverse
      lines = lines[ -MAXHISTSIZE, MAXHISTSIZE ] if lines.nitems >
MAXHISTSIZE
      $stderr.puts "Saving %d history lines to %s." %

        [ lines.length, histfile ] if $VERBOSE || $DEBUG
      File::open( histfile, File::WRONLY|File::CREAT|File::TRUNC ) {|
ofh>
        lines.each {|line| ofh.puts line }
      }
    }
  end
end

#### And this for RI (again, from Rubygarden or someone's blog, I forget
which):

def ri arg
   puts `ri #{arg}`
end

class Module
   def ri(meth=nil)
     if meth
       if instance_methods(false).include? meth.to_s
         puts `ri #{self}##{meth}`
       else
         super
       end
     else
       puts `ri #{self}`
     end
   end
end

···

On Thu, 2006-10-12 at 21:32 +0900, Dr Nic wrote:

I recently discovered that I can create a .irbrc file to run setup for
my irb/console. I am in love.

...

Does anyone any interesting things in their .irbrc file?

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Dr Nic wrote:

Does anyone any interesting things in their .irbrc file?

This is useful sometimes:

def dump_history(file=nil)
   if file
     File.open(file, "w") do |f|
       f.puts IRB::ReadlineInputMethod::HISTORY.to_a
     end
   else
     puts IRB::ReadlineInputMethod::HISTORY.to_a
   end
end

And there is this gem from Logan Capaldo:

def reset_irb
   exec($0)
end

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

I don't know why I hadn't thought of it before but I just added:

# show_regexp - stolen from the pickaxe
def show_regexp(a, re)
   if a =~ re
      "#{$`}<<#{$&}>>#{$'}"
   else
      "no match"
   end
end

# Convenience method on Regexp so you can do
# /an/.show_match("banana")
class Regexp
   def show_match(a)
       show_regexp(a, self)
   end
end

···

On 10/12/06, Dr Nic <drnicwilliams@gmail.com> wrote:

Does anyone any interesting things in their .irbrc file?

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/

Farrel Lifson wrote:

···

On 12/10/06, Dr Nic <drnicwilliams@gmail.com> wrote:

I haven't used it but Wirble(http://pablotron.org/software/wirble/\)
looks pretty cool.

Very nifty indeed.

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

Funny reading through the code. I spotted a few screw-ups. Probably a
side effect of doing rapid and small changes between irb_reset's.

Brian.

···

On 10/12/06, Brian Mitchell <binary42@gmail.com> wrote:

On 10/12/06, Dr Nic <drnicwilliams@gmail.com> wrote:
> I recently discovered that I can create a .irbrc file to run setup for
> my irb/console. I am in love.
>
> My current .irbrc is:
>
> require 'irb/completion'
> require 'map_by_method'
> require 'what_methods'
> require 'pp'
> IRB.conf[:AUTO_INDENT]=true
>
> Explanation of the different libraries:
> http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/
>
> Does anyone any interesting things in their .irbrc file?
>

Mine is rather large and in flux right now but I will post a few
nuggets from it bellow:

require 'rubygems'

# Very basic prelude of enhancements for Object
module ObjectEnhancer

  def clone!
    self.clone rescue self
  end

  def tap
    yield self
    self
  end

  def _
    yield if block_given?
    nil
  end

end

class Object
  include ObjectEnhancer
end

# Lazy loading prety print support
class Object
  def pp(*a, &b) # pass the block just-in-case this changes.
    require 'pp'
    pp(*a, &b)
  end
end

# Tab completion
require 'irb/completion'
IRB.conf[:USE_READLINE] = true

# Histories
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:EVAL_HISTORY] = 100

# Prompts
IRB.conf[:PROMPT][:CUSTOM] = {
    :PROMPT_N => ">> ",
    :PROMPT_I => ">> ",
    :PROMPT_S => nil,
    :PROMPT_C => " > ",
    :RETURN => "=> %s\n"
}

# Set default prompt
IRB.conf[:PROMPT_MODE] = :CUSTOM

# Simple ri integration
def ri(*names)
  system("ri #{names.map {|name| name.to_s}.join(" ")}")
end

# fresh irb. It uses an at_exit handler to yield it a block is given.
def reset_irb
  at_exit {exec($0)} # first registered is last to run
  at_exit {yield if block_given?}

  # From finalizer code in irb/ext/save-history.rb.. very ugly way to
do it :S.. who wants to rewrite irb?
  if num = IRB.conf[:SAVE_HISTORY] and (num = num.to_i) > 0
    if hf = IRB.conf[:HISTORY_FILE]
      file = File.expand_path(hf)
    end
    file = IRB.rc_file("_history") unless file
    open(file, 'w') do |file|
      hist = IRB::HistorySavingAbility::HISTORY.to_a
      file.puts(hist[-num..-1] || hist)
    end
  end

  # Make irb give us a clean exit (up until our at_exit handler above)
  throw :IRB_EXIT, 0
end

# clear the screen.. with some self destruction :wink:
def clear
  eval "def clear; print #{`clear`.inspect} end"
  clear
end
private :clear

# Simple webserver (Loazy loading)
def serve_files(opts = {})
  require 'webrick'

  opts[:host] ||= Socket.gethostname
  opts[:dir] ||= Dir.pwd
  opts[:port] ||= opts[:dir].hash % 1000 + 10000
  opts[:log] ||= Nop.new # hidden and simple.

  server = WEBrick::HTTPServer.new(
    :Host => opts[:host],
    :Port => opts[:port],
    :DocumentRoot => opts[:dir],
    :Logger => opts[:log]
  )

  trap("INT") {server.shutdown}

  puts "Serving \"#{opts[:dir]}\" at http://#{opts[:host]}:#{opts[:port]}/"
  server.start
  nil
rescue
  puts "Failed to start server! See $webrick_error for the exception."
  $webrick_error = $!
  nil
end
private :serve_files

# SSH support. Needs a lot of work still but it is nice to have.
# This was just a 5 min hack. Thanks goes to Jamis for the
# nice library.
# Note that you must sleep to have the event loop run.
def ssh_session(opts = {})
  puts "Note: You must 'sleep' in order for the event loop to run in
irb." if require 'net/ssh'

  dynamic_session_class = Class.new do
    @@default_opts = {
      :user => ENV['USER'] || ENV['USERNAME'],
      :port => 22
    }.freeze

    def initialize(opts = {}, aux = {})
      opts, opts[:host] = aux, opts unless Hash === opts
      opts = aux.merge opts
      opts = @@default_opts.merge opts

      @shutdown = false
      @queue =

      ready = false
      Thread.new {
        begin
          Net::SSH.start(opts[:host],
            :username => opts[:user],
            :password => opts[:password],
            :port => opts[:port]
          ) do |session|
            ready = true
            loop {
              break if self.shutdown?
              self.process(session)
              session.loop
              sleep 0.01
            }
          end
        rescue
          puts "Failed while running ssh session! See $ssh_error for
the exception."
          $ssh_error = $!
        ensure
          ready = true
        end
      }
      sleep 0 until ready
    end

    def shutdown?
      @shutdown
    end

    def shutdown
      @shutdown = true
    end

    def execute(&blk)
      raise "Session shutdown" if shutdown?
      @queue << blk
      nil
    end

    def process(session)
      while proc = @queue.pop
        proc.call(session)
      end
    end

    def forward_local(port, host, aux_port = port)
      execute {|session|
        session.forward.local('0.0.0.0', port, host, aux_port)
      }
    end
    alias outgoing forward_local

    def forward_remote(port, host, aux_port = port)
      execute {|session|
        session.forward.remote_to(port, host, aux_port)
      }
    end

    def shell
      require 'termios'
      puts "Note: You will need to interrupt 'sleep' when your shell
is done (usually ^C)."
      execute {|session|
        stdin_buffer = lambda do |enable|
          attrs = Termios::getattr($stdin)
          if enable
            attrs.c_lflag |= Termios::ICANON | Termios::ECHO
          else
            attrs.c_lflag &= ~(Termios::ICANON | Termios::ECHO)
          end
          Termios::setattr($stdin, Termios::TCSANOW, attrs)
        end

        begin
          stdin_buffer[false]

          shell = session.shell.open(:pty => true)

          loop do
            break unless shell.open?
            if IO.select([$stdin],nil,nil,0.01)
              data = $stdin.sysread(1)
              shell.send_data data
            end

            $stdout.print shell.stdout while shell.stdout?
            $stdout.flush
          end
        ensure
          stdin_buffer[true]
        end
      }
      sleep
    end
    alias incoming forward_remote

  end

  Object.const_set('DynamicSSHSession', dynamic_session_class) unless
Object.constants.include? 'DynamicSSHSession'

  dynamic_session_class.new(opts)
rescue
  puts "Failed to create an ssh session! See $ssh_error for the exception."
  $ssh_error = $!
end
private :ssh_session

# Like haskell's sequence. Really nice to have but recursive.
# I should change this it an iterative solution sometime.
# Recursion is usually not a problem for realistic inputs.
class Array
  def sequence(i = 0, *a)
    return [a] if i == size
    self[i].map {|x|
      sequence(i+1, *(a + ))
    }.inject() {|m, x| m + x}
  end
end

class Symbol
  def to_proc
    lambda {|*args| args.shift.__send__(self, *args)}
  end
end

# Modulized blank slate. Only removes current not future
# methods for simplicities sake.
module Blank
  def self.append_features(base)
    base.module_eval {
      instance_methods.each {|m| undef_method m unless m =~ /^__/}
    }
  end
end

# This is mostly a toy but it has been useful in a few cases
# where I needed to slowly build up a proc inside multiple
# calls
class It < Proc
  instance_methods.each {|m| undef_method m unless m =~ /^__/}

  def method_missing(*args, &blk)
    It.new {|x|
Proc.instance_method(:call).bind(self).call(x).send(*args, &blk)}
  end
end

def it
  if block_given?
    It.new
  else
    It.new {|x| x}
  end
end
private :it

That is about half of it. I've got more stuff like gray number stuf,
unbound method extensions, and some new meta-programming stuff but it
all needs a little more work first. I should also note that I wrap my
irbrc file with a begin rescue end. The rescue just prints the
presence of an error and then shoves $! into $irbrc_error. This is
nice for occasions when you might be trying out new 1.9 builds or use
rails (they don't correctly initialize IRB so it causes failed loads
of irbrc -- keeps the output a little cleaner).

I will probably do another clean-up before RubyConf so we can all
share .irbrc's ;-). I'll probably end up removing more things then I
add (i.e. I really don't use Symbol#to_proc that much).

One last thing, I was wondering if anyone would be interested in a
series of gems that act as automatic irb plugins? it might be fun to
gemify some of these things.

Brian.

Ross Bamford wrote:

#### And this for RI (again, from Rubygarden or someone's blog, I forget
which):

def ri arg
   puts `ri #{arg}`
end

class Module
   def ri(meth=nil)
     if meth
       if instance_methods(false).include? meth.to_s
         puts `ri #{self}##{meth}`
       else
         super
       end
     else
       puts `ri #{self}`
     end
   end
end

I *think* that came out of my .irbrc, but it's always missed one thing: a nice notation for class methods:

irb(main):014:0> IO.ri "close"
--------------------------------------------------------------- IO#close
      ios.close => nil

···

------------------------------------------------------------------------
...

irb(main):015:0> IO.ri "open"
More than one method matched your request. You can refine
your search by asking for information on one of:
...

Of course you can always do this:

irb(main):016:0> ri "IO.open"
--------------------------------------------------------------- IO::open
      IO.open(fd, mode_string="r" ) => io
      IO.open(fd, mode_string="r" ) {|io| block } => obj
------------------------------------------------------------------------

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

@everyone - that is a great dump ideas. Very cool. (sorry for not
replying earlier - Ruby Forum's email notifier seemed to have been
playing up).

Re: RubyConf - It'd be great to see an irb_tools gem come out of the
conference now! :slight_smile:

Nic

···

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

Nice, thanks!

You may find it useful to extend your #what? with #what_returns?(x)

[1, 2, 3].what_returns?(1) #=> [ :first ]

Used in some method browsers in Squeak. Could be extended in all kinds of
ways - state change, parameters,...

It's sad you mention that. Ironic too [1]. I had to cancel my trip
yesterday on request from the company I work for. I'll definitely miss
going but I'll avoid thinking about it to avoid souring the rest my
week too badly. So... please take great notes!

I still want to sit down and clean up my irb stuff into plugins. Maybe
I'll setup a Rubyforge project after crunch time has died down at
work. BUT don't let that stop anyone from beating me to the punch.

Brian.

[1] I have been sad to see many friends cancel their trips as well
telling them I would miss their attendance.

···

On 10/18/06, Dr Nic <drnicwilliams@gmail.com> wrote:

@everyone - that is a great dump ideas. Very cool. (sorry for not
replying earlier - Ruby Forum's email notifier seemed to have been
playing up).

Re: RubyConf - It'd be great to see an irb_tools gem come out of the
conference now! :slight_smile:

Brian Mitchell wrote:

@everyone - that is a great dump ideas. Very cool. (sorry for not
replying earlier - Ruby Forum's email notifier seemed to have been
playing up).

Re: RubyConf - It'd be great to see an irb_tools gem come out of the
conference now! :slight_smile:

It's sad you mention that. Ironic too [1]. I had to cancel my trip
yesterday on request from the company I work for. I'll definitely miss
going but I'll avoid thinking about it to avoid souring the rest my
week too badly. So... please take great notes!

I misconstrude my attendence - I'm not able to go. Went to Railsconf,
wife said "that will be sufficient for you for the year" (we're in
Europe). Bummer. But she's excited about Railsconf2007 - she wants to go
on holidays in California :slight_smile:

I still want to sit down and clean up my irb stuff into plugins. Maybe
I'll setup a Rubyforge project after crunch time has died down at
work. BUT don't let that stop anyone from beating me to the punch.

Remember to use newgem scaffolding for all your new gem generation needs
:slight_smile:

http://drnicwilliams.com/2006/10/11/generating-new-gems/

Nic

···

On 10/18/06, Dr Nic <drnicwilliams@gmail.com> wrote:

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

I've been using this guy for code that prints copious output to the
terminal. I'm sure it could be improved a bit, but I've found it
useful.

  def less
    require 'stringio'
    $stdout, sout = StringIO.new, $stdout
    yield
    $stdout, str_io = sout, $stdout
     IO.popen('less', 'w') do |f|
       f.write str_io.string
       f.flush
       f.close_write
     end
  end

I tend to use that in conjunction with yaml dumps to look at complex
data structures, rather than pp, but that would work just as well.

  def yp(*data)
    require 'yaml'
    puts YAML::dump(*data)
  end

Give them a whirl like so:

  $ irb
  less { yp IRB.conf }

···

--
Lou.