Ruby でランチャーを作る

Ruby の練習として、以下のページを参考にランチャーを作ったのだけど、うまく動かなかった。


10分でできる初めてのRubyプログラム - インターネットコム


そこで、自分なりに考えて、オリジナルのコードにちょこっと手を加えた。動作確認用に無駄なコードとか入ってるけど、とりあえずメモ。

launcher.rb(動作確認用コードのみの追加)
#!/usr/bin/ruby

# Example application to demonstrate some basic Ruby features
# This code loads a given file into an associated application

class Launcher
  def initialize( app_map ) 
    @app_map =  app_map
  end
  # Execute the given file using the associate app
  def run( file_name )
    p "in run a"
    application = select_app( file_name )
    system( "#{application} #{file_name}" ) 
  end

  # Given a file, look up the matching application
  def select_app( file_name )
    ftype = file_type( file_name )
    @app_map[ ftype ]
  end

  # Return the part of the file name string after the last '.'
  def file_type( file_name )
    File.extname( file_name ).gsub( /^./, '' ).downcase 
  end
end
launcherx.rb(動作確認用コードのみの追加)
#!/usr/bin/ruby

# File launcherx.rb

require 'launcher'

class Launcher

  def handler( file )
    p "in handler"
    get_handler(file) ||  build_handler(file)
  end

  def build_handler file
    handler = Class.new 
    application = select_app(file)
    eval "def handler.run 
      system( '#{application} #{file}' ) 
    end" 
    handler
  end

  def get_handler(file)
    begin
      p "in get_handler"
      # File.dirname(__FILE__ )だけで十分じゃない?
      here  = File.expand_path( File.dirname(__FILE__ ))
      ftype =  file_type(file)
      p "#{here}/handlers/#{ftype }"
      p ftype.capitalize
      require "#{here}/handlers/#{ftype }" 
      Object.const_get( ftype.capitalize ).new
    rescue Exception
      nil
    end
  end

  # Execute the given file using he associate app
  def run( file, args  = nil )
    p "in run"
    p "#{file} #{args}"
    p handler(file).run(file, args)
  end
end
html.rb(handlers フォルダの下に置く。go.rb に対応させて変えてある。)
class Html

  DEFAULT_BROWSER = 'w3m'

  def run(file, args)
    if args.empty?
      system( "#{DEFAULT_BROWSER} #{file}" ) 
    else
      dispatch_on_parameters file, args
    end
  end

  def dispatch_on_parameters file, args
    p args.class
    p "fuga#{args}"
    tmp = args.split(' ')
    cmd = tmp.shift
    args2 = tmp.join(' ')
#    p "#{cmd}"
    send( "do_#{cmd}", file, args2 )
  end

  def do_opera file, args=nil
    system( "opera #{file}  #{args}" )
  end

  def do_konq file, args=nil
    system( "konqueror #{file}  #{args}" )
  end

  def do_emacs file, args=nil
    system( "emacs #{file}  #{args}" )
  end
end
go.rb(Launcher#run への引数の渡し方を変えた)
#!/usr/bin/ruby

require 'launcherx'

# Script to invoke launcher using command-line args
def help
  print " 
  You must pass in the path to the file to launch.

  Usage: #{__FILE__} target_file
" 
end
if ARGV.empty?
  help
  exit
else
  app_map = {
     'html' => 'vi',
     'rb' => 'vi',
#     'jpg' => 'gimp'
  }

  l = Launcher.new( app_map )
  target = ARGV.shift
  args = ARGV.join( ' ' )
  #  p target
#  p ARGV[0]
#  p ARGV[1]
  l.run( target, args )
end


以下に実行例を示しておく。

% ruby go.rb hoge.html emacs


とすると emacs hoge.html としたのと同じ。

ruby go.rb hoge.html


だったら、デフォルトの w3m hoge.html が実行される。

ruby go.rb hoge.html vi


だと、do_vi なんてメソッドが無いので、NoMethodError が投げられて終了。これは仕様という事で…。


以上。
細切れの時間にやったのでいろいろと勘違いしてるかもしれない。