金子邦彦研究室プログラミングRuby プログラミングRuby 入門

Ruby 入門

Ruby 入門

関連する外部ページ】: http://www.ruby-lang.org/ja/documentation/: Ryby のオンラインマニュアル

関連する外部ページ】: https://d.hatena.ne.jp/secondlife/20061010/1160453355; RUby で debug する 7つの方法 の Web ページ.とても役に立つ情報が載っています.

ri コマンド

ri とは,Ruby のリファランスを見るコマンド.便利.

[image]

RubyGems

登録されている gem の情報を得るには「gem query -db」を使う.

gem query -db

Ruby の習慣

キーボード

stty raw
irb
STDIN.getc

Ruby スクリプトの文字コードの設定

■ Ruby 1.8 では先頭行に shebang を使って指定する(のがおすすめ)

■ Ruby 1.9 では先頭行に magic comment を書く(のがおすすめ)

magic comment の例は次の通り.

shbang と magic comment の両方を指定したい場合には,1行目を shebang, 2行目を magic comment.

Ruby の文字列

文字列の先頭と末尾の改行文字と空白文字の削除

[image]

大文字,小文字への変換

chomp: 末尾の改行文字 \r, \n の除去


"hoge\n".chomp

[image]

squeeze: 同一の文字の並びを1つにまとめる

div class="kbd">


"I  like      an apple\n".squeeze(" ")

[image]

■ 実行結果の例

文字列中の文字を全て大文字あるいは小文字に変換

[image]

特定の文字,文字列の出現回数を調べる

[image]

文字列のマッチング

これは,マッチする文字列を含むかの判定


/a/ =~ "abc"

[image]

文字列の置換


'"fukuoka"'.gsub('"','""')

[image]

正規表現

「<」と「>」で囲まれた部分の除去


gsub(/<([^>]+?)>/, ",")

[image]

「(」が1個以降あり,その後で「)」が出てくるかの判定


#! ruby -Ks
# coding: windows-31j

require 'pp'

str = "R(a, b, c)"

# ( と ) をこの順で含むかの判定
if (/^[^\(]+\([^\)]+\).+\Z/ = str)
  p $&
end

[image]

"r(x,y,z(10),a(10));" のような文字列があったとき,次のようなことを行う. Ruby のマッチングは,デフォルトでは「欲張りマッチング」なので,最後の「)」がくるまでの文字列を取り出すのは簡単です.

  • "r" : 最初の「(」が出てくるまでの文字列
  • "x,y,z(10),a(10)" : 最初の「(」が出てきてから,最後の「)」がくるまでの文字列
  • ";": 最後の「)」が出てきた以降の文字列


"r(x,y,z(10),a(10));".match /([^(]+)\((.+)\)(.)*/

[image]

今度は UTF-8 形式のファイルを読み込み,「TITLE」タグ.「著者」タグで囲まれた文字列を得る.

  • 欲張りマッチングではうまくいかない.「?」を付ける
  • マッチする部分が2箇所以上ありえるので scan を使う.
  • Ruby スクリプトの文字コードは,Windows-31J に設定しているので,マッチングの時点で,文字列を Windows-31J に変換する

#! ruby -Ks
# coding: windows-31j

require 'pp'

if ( RUBY_VERSION < "1.9" )
  exit
end

f = File.open('/tmp/test.xml', 'r:utf-8')
a = f.read
f.close

p a.gsub(/\t|\r|\n|\f/,' ').encode('Windows-31J').scan /<TITLE>(.+?)<\/TITLE>/
p a.gsub(/\t|\r|\n|\f/,' ').encode('Windows-31J').scan (/<著者>(.+?)<\/著者>/)

[image]

Ruby の配列 (Array)

  • コンストラクタ

    配列のコンストラクタは,[ ] の中に要素を並べる

    [image]

    Array.new で,配列のサイズと初期値を指定できる

    [image]
  • 添字による参照

    [ ] の中に数値を指定するか,「,」で区切って開始位置と長さを指定するか,「..」で区切って開始位置と終了位置を書く.

    [image]
  • 末尾への要素の追加 「a = [ ]」の行はコンストラクタ.「a << "apple"」などは末尾への要素の追加

    
    #! ruby -Ks
    # coding: windows-31j
    
    require 'pp'
    
    a = [ ]
    a << "apple"
    a << "orange"
    a << "banana"
    
    p a
    pp a
    

    [image]
  • include? 要素の包含

    
    [1, 2, 3].include?(2)
    [1, 2, 3].include?(4)
    

    [image]
  • any? 条件を満たす要素が1つでもあるか?

    
    [2,3,5,7].any? {|i| 8 % i == 0}
    [3,5,7].any? {|i| 8 % i == 0}
    

    [image]
  • all? 条件を,全ての要素が満たすか?

    
    [2,3,5,7].any? {|i| 8 % i == 0}
    [3,5,7].any? {|i| 8 % i == 0}
    

    [image]
  • each による繰り返し

    
    [1,2,3,4].each do |e|
      p e * 10
    end
    

    [image]
  • each_with_index による繰り返し

    添字番号を得る

    
    a = ["apple", "orange", "banana"]
    a.each_with_index do |e, index|
      p "#{index}: #{e}"
    end
    

    [image]
  • map による繰り返し

    同一のメソッドを,各要素に適用することを繰り返す.結果を配列として得る

    
    [1,2,3,4].map{|i| i * s|
    

    [image]

    
    a = ["apple", "orange", "banana"]
    p a.map{|e| e.length}
    p a.map{|e| "element = #{e}"}
    

    [image]
  • + を用いた Array の和

    [image]
  • join を用いた Array の要素の連結

    [image]

Ruby のハッシュ (Hash)

  • new: コンストラクタ

    [image]
  • キーと値の追加
  • key?, value? キーと値に関する包含

    [image]
  • delete による削除

    [image]
  • map による繰り返し

    同一のメソッドを,各要素に適用することを繰り返す.

    [image]

ヒアドキュメントと YAML

プログラムの例

require 'yaml'
a = <<-EOS
- g: fruits
  s: 
  - apple
  - orange
  - banana
  - watermelon
EOS

p.a
p YAML.load( a )

ブロック構文による繰り返し

  • each do .. end : 要素を順にたどる
  • each_line do .. end : 文字列の各行について繰り返し処理
  • each_byte do .. end : 文字列の各バイトについて繰り返し処理
  • scan(expression) do .. end : 正規表現 expression にマッチするような部分文字列について繰り返し処理


a = Array.new(["1", "2", "3", "4", "5"])
a.each do |item|
    p item
end


str = <<STR
1 apple
2 orange
3 lemon
STR
i = 1
str.each_line do |line|
    p i
    p line
    i += 1
end

[image]

ブロック構文による資源管理

例えば,ファイルのオープンについてブロック構文を使うと,ファイルのクローズが保障される.


#! ruby -Ks
# coding: windows-31j

require 'pp'

# Windows の場合の書き方
# FILENAME="C:\\hoge.txt"
# Linux の場合の書き方
FILENAME="/tmp/hoge.txt"

File.open(FILENAME, "r") do |f|
  c = 1
  f.each_line do |line|
    p c
    p line
    c += 1
  end
end

[image]

ファイル

  • バイナリモードへの設定

    
      File.open( fname, "r") do |f2|
        f2.binmode
        ...
      end
    
  • File.basename basename の取得

    [image]
  • File.extname extname の取得

    [image]
  • split(".",2) 最初の「.」を区切りとして,文字列を 2つの文字列に分割するときの決まり文句

    [image]
  • File.dirname ディレクトリ名の取得

    [image]
  • File.expand_path 相対パスの絶対パスへの変換

    [image]
  • Dir.chdir カレントディレクトリの変更

    [image]
  • Dir.glob ファイル名のパターンマッチ
  • Dir.mktmpdir: 作業用に使える一時的なディレクトリ

    [image]

メタプログラミングによるセッター,ゲッターの定義の例

下記の例では, 「id=」,「name=」,「price=」という3つのセッター(setter)メソッドを呼び出している.

#! ruby -Ks
# coding: windows-31j

class Commodity
    attr_accessor :id, :name, :price
    def to_s
      "(#{@id}, #{@name}, #{@price})"
    end
end

c = Commodity.new
c.id = 1010
c.name = "apple"
c.price = 12.34
puts c

[image]

ゲッター (getter) メソッドを使う例は次の通り. 「id」,「name」,「price」という3つのゲッターメソッドを呼び出している.


puts c.id
puts c.name
puts c.price

Ruby ではインスタンスの属性に直接アクセスする方法はない(必ずメソッドが介在する).

クラス名,メソッド一覧の取得

  • class: クラス名の取得

    [image]
  • methods: メソッド一覧の取得

    [image]

無名クラスの例


#! ruby -Ks
# coding: windows-31j

require 'pp'

def gen_new_class(attr_list)
# 無名クラスを生成し,initialize とアクセサを付ける.

# 仮に attr_list = ["x", "y", "z"] のとき
# instance_var_list => ["@x", "@y", "@z"] (各要素の頭に「@」をつけたもの)
# できる無名クラスの initaizlize は
#   def initialize(); @x, @y, @z = nil; end
# できる無名クラスのアクセサは
#   attr_accessor; :x; end
#   attr_accessor; :y; end
#   attr_accessor; :z; end
# 使い方の例は:
#   c = gen_new_class(["x", "y", "z"])
#   a = c.new
#   a.x = 100
#   p a.x
  instance_var_list = attr_list.collect{|a| "@#{a}"}
  c = Class.new
  # initialize
  c.module_eval "def initialize(); #{instance_var_list.join(',')} = nil; end"
  # アクセサ
  attr_list.each do |a|
    c.module_eval "attr_accessor :#{a}"
  end
  return c
end

if __FILE__ == $0
  c = gen_new_class(["x", "y", "z"])
  a = c.new
  a.x = 100
  p a.x
  a.y = 200
  p a.y
  a.z = 300
  p a.z
end

[image]

Ruby Java Bridge を動かしてみる

参考ページ: 「Ruby Library Report 【第 2 回】 Java との連携」の Web ページ, http://jp.rubyist.net/magazine/?0003-RLR に記載のサンプルプログラムを動かしてみました.


#! ruby -Ks
# coding: windows-31j

require 'rjb'

# Java
s = Rjb::import('java.lang.System')
s.out.println("Hello World!")
s.out.println("こんにちは! 「㈱‖〜−¢£¬|」")

# Ryby
p "Hello World!"
p "こんにちは! 「㈱‖〜−¢£¬|」"

■ ActiveScriptRuby 1.8.7-p174 での実行例 ※ 文字化けします.要注意(対処法は手付かず)

[image]

プログレスバーの表示

■ インストールの手順


gem install progresspar

■ プログラム動作例


require 'rubygems'
require 'progressbar'
bar = ProgressBar.new("progress", 8)
10.times do |e|
  print e
  bar.inc
end
bar.finish

[image]

標準入力からの読み込み

gets を使用

[image]

外部コマンドの起動

system を使用

WIN32OLE

Web ページの検索フォームを自動的に設定する例


#! ruby -Ks
# coding: windows-31j

# http://jp.rubyist.net/magazine/?0003-Win32OLE
require 'win32ole'

def open_ie(url)
  ie = WIN32OLE.new('InternetExplorer.Application')
  ie.Navigate(url)
  ie.Visible = true
  while ie.busy
    sleep 1
  end
  return ie
end
 
def ie_form_value(ie, name, val)
  f = ie.document.all.Item(name)
  f.Value = val
end

def ie_button_click(ie, name)
  b = ie.document.all.Item(name)
  b.click()
end

ie = open_ie("https://auctions.yahoo.co.jp/jp/")
# 検索フォーム
ie_form_value(ie, "AucSearchTxt", "ruby")
# 検索ボタン
ie_button_click(ie, "submitBtn")


ie = open_ie("http://www.google.co.jp/")
# 検索フォーム
ie_form_value(ie, "q", "ruby")
# 検索ボタン
ie_button_click(ie, "btnG")