[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

My .irbrc for console/irb

Dr Nic

10/12/2006 12:33:00 PM

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-c...

Does anyone any interesting things in their .irbrc file?

Nic

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

13 Answers

Farrel Lifson

10/12/2006 12:59:00 PM

0

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-c...
>
> Does anyone any interesting things in their .irbrc file?
>
> Nic
>
> --
> Posted via http://www.ruby-....
>
>

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

Farrel

Dr Nic

10/12/2006 1:19:00 PM

0

Farrel Lifson wrote:
> On 12/10/06, Dr Nic <drnicwilliams@gmail.com> wrote:
>>
>>
> I haven't used it but Wirble(http://pablotron.org/softwa...)
> looks pretty cool.

Very nifty indeed.

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

Its Me

10/12/2006 3:09:00 PM

0

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,...





Brian Mitchell

10/12/2006 3:32:00 PM

0

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-c...
>
> 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 ;-)
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 + [x]))
}.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.

Brian Mitchell

10/12/2006 3:36:00 PM

0

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-c...
> >
> > 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 ;-)
> 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 + [x]))
> }.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.
>

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.

Ross Bamford

10/12/2006 4:54:00 PM

0

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?

### 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

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


Joel VanderWerf

10/13/2006 4:42:00 AM

0

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

Joel VanderWerf

10/13/2006 4:44:00 AM

0

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

Rick DeNatale

10/13/2006 7:48:00 PM

0

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

> Does anyone any interesting things in their .irbrc file?

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



--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

IPMS/USA Region 12 Coordinator
http://ipmsr12.denh...

Visit the Project Mercury Wiki Site
http://www.mercuryspace...

Dr Nic

10/18/2006 8:44:00 AM

0

@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! :)

Nic

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