ランプの中身(Ruby on Railsのシステム開発)
ランプの中身(Ruby on Railsのシステム開発)では、株式会社ケイビーエムジェイのRuby on Railsエンジニアが蓄積したノウハウを公開しています。Ruby on Railに関する技術解説や実践的なノウハウなど、開発現場の技術に則したコンテンツを随時追加していきます。 初心者の方でもわかりやすい技術解説を心がけています。リクエスト、ご質問も受け付けいますので、お気軽にコメントを記述して下さい。

< Rubyのソースコードから HTML H... | メイン  |  sshでrootログ... >

saronpasuの中身(ruby
2008.06.09

Rubyプログラムの組み方から、Exeファイルの作成まで

こんばんは、saronpasuです。

 

今回は、RubyからWindowsの実行ファイル Exeを作ってみます。

 RubyプログラムをExeファイルにすることで、Rubyがインストールされていない

 他のWindowsマシンでも自分の作ったプログラムが実行できるようになります。

 

Exeファイルの生成だけならとても簡単です。

せっかくですから、実際にどうやってRubyプログラムを組むのかがわかるように、プロトタイプを作りながら説明して参ります。

 

 

 

概要 

 

まず、作りたいサンプルプログラムの内容です。

 

要件

 ・テキストファイルをパースして、特定の文字を含むかどうかを判定する

 ・ファイルは操作は、ドラック&ドロップで行う

 ・RubyがインストールされていないWindowsマシンで動作する

 

こんなものを作ってみます。

 

プロトタイプ1「ただ終了するだけ」 

 

まずは、Rubyで動作するexample.rbというサンプルコードを構築してみましょう。

 

#!ruby

 exit if ARGV.empty?

 

はい。

引数が空っぽの場合は終了する。という内容です。

ここにコードを足して行きます。

 

 プロトタイプ2「ファイルの存在を確認」

 

#!ruby

exit if ARGV.empty?

 

file_list = ARGV.find_all do |i|

   File.exist?(i)

end

puts file_list 

 

はい。

引数に渡されたファイルがちゃんと存在するかどうかを確認して、

存在するファイルのリストを生成します。

ちなみに、ARGVというのは、標準入力に渡された引数が入る配列のことを示します。

File.exist?というのは、ファイルの存在確認をするメソッドです。 

 

$ ruby example.rb file_a.txt file_b.txt not_found.txt

-> file_a.txt

file_b.txt 

 

試しに実行してみると、このような結果になります。 

 

#!ruby

exit if ARGV.empty?

 

file_list = ARGV.find_all do |i|

   File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)

 end

puts file_list 

 

はい。

さきほどの処理にさらに条件を追加しました。

「1バイト以上のファイルが存在し、なおかつ読み取り可能であること」という条件です。

 

$ ruby example.rb file_a.txt zero_byte.txt not_found.txt it_is_directory

-> file_a.txt

 

このような結果になります。 

 

プロトタイプ3「伝家の宝刀、パターンマッチ!」 

 

#!ruby

exit if ARGV.empty?

 

file_list = ARGV.find_all do |i|

   File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)

end 

 

pattern = /^.*(do).*(ru).*(by).*$/m

 

これから検索する正規表現パターンを生成しました。

テキストの中身に、「do」「ru」「by」という文字が、順番通りに含まれるかどうかを調べます。

正規表現オブジェクト『//』に、mオプションをつけることで、複数行にマッチングするようになります。 

 

 #!ruby

exit if ARGV.empty?

 

file_list = ARGV.find_all do |i|

   File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)

end 

 

pattern = /^.*(do).*(ru).*(by).*$/m

 

match_list = file_list.find_all do |j|

   open(j, 'r'){|k|

     k.read.match(pattern)

   }
end 

puts match_list 

 

はい。

 ファイルリストをそれぞれ開いて、中身のテキストをパースして正規表現パターンにマッチするかどうかを調べています。

 

 $ ruby example.rb match.txt unmatch.txt

-> match.txt

 

実行してみると、このような結果になります。 

 

プロトタイプ4「ポップアップを表示する」

 

#!ruby

require 'win32ole' 

exit if ARGV.empty?

wsh = WIN32OLE.new('WScript.Shell')

 

file_list = ARGV.find_all do |i|

   File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)

end 

 

pattern = /^.*(do).*(ru).*(by).*$/m

 

match_list = file_list.find_all do |j|

   open(j, 'r'){|k|

     k.read.match(pattern)

   }
end

 

wsh.popup('match!', 0, 'Do Ruby!') unless match_list.empty?

 

はい。

処理結果として、正規表現パターンにマッチする場合はポップアップメッセージを表示します。

今回は、ポップアップを表示するためにWin32OLEライブラリを使って、

Windows Scripting Host の、WScript.Shell オプジェクトを制御しました。

 

$ ruby example.rb match.txt

 Popup

このような結果になります。 

 

このままでは少々、不格好ですので整形します。

 

#!ruby -Ks

require 'kconv' 

require 'win32ole'

exit if ARGV.empty?

 

def search(argument, pattern_string)

  file_list = ARGV.find_all do |i|
    File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)
  end

  pattern = Regexp.new(pattern_string, Regexp::MULTILINE)

  

  match_file = file_list.find_all do |filename|

    open(filename, 'r'){|f|

      f.read.match(pattern)

    } 

  end
 

  return match_file

end 

 

def popup(message)

  wsh = WIN32OLE.new('WScript.Shell')

  wsh.popup(message, 0, 'Do Ruby!')
end 

 

pattern = "^.*(Do|dO).*(Ru|rU).*(By|bY).*$" 

unless search(ARGV, pattern,

   popup('match!')

end 

 

はい。

処理をメソッドに分けて、少しばかり正規表現パターンを変えました。

 

プロトタイプ5「マルチバイト対応」

 

ついでに、マルチバイト対応もしてみましょう。

 

#!ruby

require 'win32ole'

exit if ARGV.empty?

 

def search(argument, pattern_string, 's')

  file_list = ARGV.find_all do |i|
    File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)
  end

  pattern = Regexp.new(pattern_string, Regexp::MULTILINE)

  

  match_file = file_list.find_all do |filename|

    open(filename, 'r'){|f|

      f.read.tosjis.match(pattern)

    } 

  end
 

  return match_file

end 

 

def popup(message)

  wsh = WIN32OLE.new('WScript.Shell')

  wsh.popup(message, 0, 'Do Ruby!')
end 

 

pattern = "^.*(Do|dO).*(Ru|rU).*(By|bY).*$" 

unless search(ARGV, pattern,

   popup('match!')

end 

 

はい。これで、Windows環境とはことなる文字コードのテキストでも解析できるようになりました。

マルチバイト対応には、Kconvライブラリを使いました。

 

Exerb登場! 

 

それでは、いよいよお待ちかねのExeを作成しましょう。

 Exeの作成には、『Exerb』というソフトウェアを使用します。

 

Exerbをインストールした状態で、次のコマンドを実行します。

 

$ mkexy example.rb

 

これで、Exe作成用のレシピファイルが生成されました。

レシピファイルというのは、Exeの生成に必要な設定ファイルです。 

 

作成されたレシピファイル

 

# Generated by mkexy

# on 2008-06-09 21:06



general:

  startup: example.rb

  core: cui

  kcode: sjis



file:

  example.rb:

  win32ole.so:

    file: c:/ruby/lib/ruby/1.8/i386-mswin32/win32ole.so

    type: extension-library

  nkf.so:

    file: c:/ruby/lib/ruby/1.8/i386-mswin32/nkf.so

    type: extension-library

  kconv.rb:

    file: c:/ruby/lib/ruby/1.8/kconv.rb

 

 

次に、このレシピファイルを開いてファイルの最後に4行だけ追記しましょう。

 

  stringio.so:

     file: C:/ruby/lib/ruby/1.8/i386-mswin32/stringio.so

     type: extension-library

 

※最後の改行を含めて、4行です。 

 

Exeファイルの作成

 

ここまでできたら、あとは仕上げです。

 

$ exerb example.exy

 

このように、作成したレシピファイルを渡してあげると example.exe というExeファイルが作成されます。

 

あとは、試しに「 do hoge ru fuga by 」と書いたテキストを作って、

example.exeアイコンへドラッグ&ドロップしてみましょう。

 Popup

ちゃんと、「match!」とポップアップがでるはずです。

 

このプログラムの作成には、Ruby環境が必要ですが

作成したExeはRubyがインストールされていないマシンでも 実行できます。

 

 

おまけ

 

#!ruby

require 'win32ole'

exit if ARGV.empty?

 

def search(argument, pattern_string, 's')

  file_list = ARGV.find_all do |i|
    File.exist?(i) && File.file?(i) && File.readable?(i) && File.size?(i)
  end

  pattern = Regexp.new(pattern_string, Regexp::MULTILINE)

  

  match_file = file_list.find_all do |filename|

    open(filename, 'r'){|f|

      f.read.tosjis.match(pattern)

    } 

  end
 

  return match_file

end 

 

def popup(message)

  wsh = WIN32OLE.new('WScript.Shell')

  wsh.popup(message, 0, 'Do Ruby!')
end 

 

pattern = "^.*(ぬ|ヌ).*(る|ル).*(ぽ|ポ).*$" 

unless search(ARGV, pattern,

   popup('ガッ!')

 

end 

 

ガッ!

 

なんていうこともできますね。

 

 

コメント (0)  |トラックバック (0)

ブックマークに追加する

トラックバック URL

この記事にコメントする

ニックネーム:
メールアドレス:
URL:


KBMJのWebソリューション
Ruby on Rails Summer Festival 2008開催決定!!

TOPICS

2008/08/14
ZD Net Builder」の連載記事です。第七回は「Rubyでどう書く?:RubyCocoa+Core Animationでお手軽アニメーション」が掲載されました。

2008/08/06
ZD Net Builder」の連載記事です。第六回は「Rubyでどう書く?特別編:Matzからのお題」が掲載されました。

2008/07/29
アットマーク・アイティ」にケータイWebアプリ開発、9つの注意点が掲載されました。

2008/07/11
ZD Net Builder」の連載記事です。第五回は「Rubyでどう書く?:RubyでWord文書を作成する」が掲載されました。

全体のRoR最新ブログ一覧

プロフィール

  • saronpasu
  • RubyやRuby on Railsで開発して行く上でのTipsや、トラブルにぶつかった際の解決方法なんかを公開して行きます。

ブログの購読

RSS

timelog
株式会社ケイビーエムジェイロゴ