Rib -- Yet another interactive Ruby shell





http://godfat.org/slide/2017-04-18-rib/

Who?

Lin Jen-Shin (godfat)

  • 2001~2004: C
  • 2004~2009: ActionScript
  • 2005~2008: C++
  • 2006~2017: Ruby
  • 2007~2017: (learning) Haskell

6 years ago...

Initial commit


commit 9847d52e115efada14c52e70b0308f1c9603ad3e
Author: Lin Jen-Shin <godfat@godfat.org>
Date:   Wed Feb 23 05:15:23 2011 +0800

    first commit. code template

Why?

Why Create?
Why Not Use?









                
http://godfat.org/slide/2014-01-07-create/

Pain Threshold

But still,
why?

Programming shall be happy

Solve the problem, and be happy

ripl redo -- rib

What about now?

πŸ–Rib

A lightweight and extensible irb replacement

http://rib.godfat.org/ -- by @lulalala_it

⭐ 29 -> 125

No new
issues?
πŸ€”

Solve the problem, and be happy

How I use
it daily


17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...

Beep! πŸ”” β‘ 


Loading development environment (Rails 4.2.8)
>> |

require 'rib/more/beep'


require 'rib'

module Rib::Beep
  extend Rib::Plugin
  Shell.use(self)
end

require 'rib/more/beep'


def before_loop
  super
  return self if Beep.disabled?
  beep if
    (Time.now - config[:started_at]) >
    beep_threshold
  Beep.disable # Or Rib.disable_beep
  self
end

require 'rib/more/beep'


private

def beep
  print "\a"
end

def beep_threshold
  config[:beep_threshold] ||= 5
end

Also works in rspec anchoring


ruby -r rib/config -S rspec spec/slow_spec.rb:12

While in the code


it "is anchoring" do
  Rib.anchor binding
end

πŸ”” β‘ 

Patience
saver!


17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>> |

17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>> Trace|↑

17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>>
s = Gitlab::Ci::Trace|::Stream.new do
  open('...')
end

cat ~/.inputrc


"\e[A": history-substring-search-backward
"\e[B": history-substring-search-forward

Plugins needed


17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>>
s = Gitlab::Ci::Trace|::Stream.new do
  open('...')
end

17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>>
s = Gitlab::Ci::Trace ::Stream.new do
  open('...')
end
=> #<Gitlab::Ci::Trace::Stream:0xdeadbeef>
>> |

require 'rib/more/color'


module Rib::Color
  def format_result result
    return super if Color.disabled?
    config[:result_prompt] + format_color(result)
  end

  def get_error err
    return super if Color.disabled?
    message, backtrace = super
    [format_color(err, message),
     format_backtrace(backtrace)]
  end
end

require 'rib/more/color'


def colors
  config[:color] ||= {
    Numeric    => :red    ,
    String     => :green  ,
    Symbol     => :cyan   ,
    Array      => :blue   ,
    Hash       => :blue   ,
    NilClass   => :magenta,
    TrueClass  => :magenta,
    FalseClass => :magenta,
    Exception  => :magenta,
    Object     => :yellow }
end

require 'rib/more/color'


def format_color result, display=result.inspect
  case result
    # ... recursive
  end
end

def format_backtrace backtrace
  colorize_backtrace(super(backtrace))
end

require 'rib/more/color'


begin
  require 'win32console' if
    defined?(Gem) &&
    Gem.win_platform?
rescue LoadError => e
  Rib.warn(
    "Error: #{e}"                                                  ,
    "Please install win32console to use color plugin on Windows:\n",
    "    gem install win32console\n"                               ,
    "Or add win32console to Gemfile if that's the case"            )
  Rib::Color.disable
end

17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>>
s = Gitlab::Ci::Trace ::Stream.new do
  open('...')
end
=> #<Gitlab::Ci::Trace::Stream:0xdeadbeef>
>> Rib.edit|

require 'rib/more/edit'


require 'rib'
require 'tempfile'

module Rib::Edit
  def editor
    ENV['EDITOR'] || 'vim'
  end
end

Useful along with Rib.anchor binding
Suggested by @devpoga


17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>> Rails.application|
=> ...............................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................

17:21 godfat@godfat-01 ~/gitlab-ce master> rib auto
rib-auto: Found Rails, loading it...
Loading development environment (Rails 4.2.8)
>> Rails.application.inspect.size
=> 562023

require 'rib/extra/paging'


# Print if it fits in one screen,
# paging it through a pager otherwise.
def puts str=''
  return super if Paging.disabled?
  if one_screen?(str)
    super
  else
    page_result(str)
  end
end

def pager
  ENV['PAGER'] || 'less -R'
end

require 'rib/extra/paging'


pager = ENV['PAGER'] || 'less'

if `which #{pager}`.empty?
  Rib.warn("#{pager} is not available, disabling Rib::Paging")
  Rib::Paging.disable
elsif `which tput`.empty?
  Rib.warn("tput is not available, disabling Rib::Paging")
  Rib::Paging.disable
elsif ENV['TERM'] == 'dumb' || ENV['TERM'].nil?
  Rib.warn("Your terminal is dumb, disabling Rib::Paging")
  Rib::Paging.disable
end

17:21 godfat@godfat-01 ~/gitlab-ce master>
ruby -rrib/config -rbundler/setup -S \
rspec spec/models/ci/pipeline_spec.rb:118

πŸ”” β‘ 


#<Ci::Pipe(0)>> Rib.caller|
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................

17:21 godfat@godfat-01 ~/gitlab-ce master>
ruby -rrib/config -rbundler/setup -S \
rspec spec/models/ci/pipeline_spec.rb:118

πŸ”” β‘ 


#<Ci::Pipe(0)>> Rib.caller 'activesupport', /rspec/
  spec/models/ci/pipeline_spec.rb:119:in `block (5 levels) in <top (required)>'
  spec/models/ci/pipeline_spec.rb:102:in `block (3 levels) in <top (required)>'
  app/models/ci/pipeline.rb:220:in `retryable?'
#<Ci::Pipe(0)>> |

Plugins needed

Other plugins

Anchor in a loop


require 'rib/debug'

Rib.enable_anchor do
  # Only `Rib.anchor` called in this block
  # would launch a shell
end

# No effect (no-op) outside the block
Rib.anchor binding

My config ~/.config/rib/config.rb


require 'rib/all'
require 'rib/extra/autoindent'
require 'rib/extra/paging'

Usage: rib [ruby OPTIONS] [rib OPTIONS] [rib COMMANDS]
ruby options:
  -e, --eval LINE        Evaluate a LINE of code
  -d, --debug            Set debugging flags (set $DEBUG to true)
  -w, --warn             Turn warnings on (set $-w and $VERBOSE to true)
  -I, --include PATH     Specify $LOAD_PATH (may be used more than once)
  -r, --require LIBRARY  Require the library, before executing your script
rib options:
  -c, --config FILE      Load config from FILE
  -p, --prefix PATH      Prefix to locate the app. Default to .
  -n, --no-config        Suppress loading any config
  -h, --help             Print this message
  -v, --version          Print the version
rib commands:
  all                    Load all recommended plugins
  auto                   Run as Rails or Rack console (auto-detect)
  min                    Run the minimum essence
  rack                   Run as Rack console
  rails                  Run as Rails console

How I run rib on a GitLab node


# Ubuntu packages
sudo apt install -y build-essential cmake libicu-dev pkg-config libpq-dev ruby-dev libreadline-dev nodejs libkrb5-dev

# ENV
export PATH=~/.gem/ruby/2.3.0/bin:$PATH
export BUNDLE_APP_CONFIG=~/.bundle
root=/opt/gitlab/embedded/service/gitlab-rails

# bundler and other gems
gem install bundler rib bond readline_buffer --user --no-ri --no-rdoc

# bundle install
bundle install --gemfile $root/Gemfile --path ~/.gem --without mysql

# Run the console
sudo -E rib all -rrib/extra/autoindent -rrib/extra/paging -p $root auto production

rib app rib-rest-core


require 'rib/runner'
# create the shell before app to prvent your bundler (if any) kicks in
Rib.shell
# we need to require anything before loading the app,
# and both `rib auto` (true) and `rib-auto` (nil) should work
require 'rib/core' if Rib.config.delete(:mimic_irb) != false
require 'rib/app/rest-core'
# load the app
Rib::RestCore.load
Rib::Runner.run(ARGV)

__END__
Run as interactive rest-core client

rib -h


Usage: rib [ruby OPTIONS] [rib OPTIONS] [rib COMMANDS]
ruby options:
  ...
rib commands:
  all                    Load all recommended plugins
  auto                   Run as Rails or Rack console (auto-detect)
  min                    Run the minimum essence
  rack                   Run as Rack console
  rails                  Run as Rails console
  rest-core              Run as interactive rest-core client

rib heroku

Q?