人気ブログランキング | 話題のタグを見る

Ruby をシェルとして使う snrb

srb で入力行ごとにインスペクトが表示されるのが煩わしかったので、表示させない snrb を作った。

snrb で遊んでいたら、シェルのコマンドが `.... ` (backquote) で動かせるのに気がついた。snrb 上で a = `ls foo` のようにすると、 ls の出力を変数に取り込むことができる。取り込んだ変数は正規表現で検索したり、配列に変更したり、Rubyの機能で自由に加工できる。

自分が何をやりたかったのかがやっとわかった。Rubyでデータが加工できるシェルが欲しかったのだ。

ファイル名: snrb (open, eval は全角英数に変換して使用)

require 'readline'
include Readline

module Srb
  def Srb.edit(prog = nil)
    if prog != nil
      File.open('temp.txt','w') {|f| f.write(prog)}
    end
    system "vi temp.txt"
    prog = IO.read('temp.txt')
    system "rm temp.txt"
    prog
  end
  
  def Srb.save(path, var)
    File.open(path, 'w') {|f| f.write(var)}
  end

  def Srb.load(path)
    IO.read(path)
  end
end

def _ml
  prog = ""
  while true
    line = readline('ml*> ', true)
    break if line == ";"
    prog << line + "\n"
  end
  return prog
end

loop do
  begin
    _line = readline('srb> ', true)
    if _line == ";"
      then _line = _ml
    end
    eval(_line, TOPLEVEL_BINDING)
  rescue SyntaxError, LoadError, StandardError
    STDERR.puts "Warning: #$!"
  end
end

実行例

Ruby$ ruby snrb
srb> a = `locate open-uri`
srb> a = a.chomp
srb> prog = IO.read(a).split(/\n/)
srb> ;
lines*> for i in 1..5
lines*> puts prog[i]
lines*> end
lines*> ;
require 'stringio'
require 'time'

module Kernel
private
srb> prog.each{|l| puts l if l =~ /class|module/}
module Kernel
module_function :open
module OpenURI
raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
if target.class == URI::HTTPS
class HTTPError < StandardError
class Buffer # :nodoc:
module Meta
module OpenRead
module URI
class Generic
class HTTP
class FTP
by tnomura9 | 2008-09-26 07:51 | Ruby | Comments(0)
<< 集中と不安定化 Ruby 標準ライブラリの歩き... >>