Rubyらしさ


文字列で遊ぼう!


シンプルな文字列は''を使う


string = 'これは文字列です。'

ん~~、普通!

ちょっとフォーマットしたい時には""を使う


  1. バックスラッシュ記法でコントロール文字を埋め込みたい
  2. 変数の値を文字列にフォーマッティングしたい

こんな用途に。

age = 18
string = "これは\n文字列です。\nボク永遠の#{age}歳!!"

"#{}"の中は、かならず「式」として評価されるので、変数名がそのまま表記できる。
ちなみに、単なる計算式でもOK

主なバックスラッシュ記法

\t タブ
\n 改行
\r キャリッジリターン
\f 改ページ
\b バックスペース
\a ベル
\e エスケープ
\s 空白
\nnn 8 進数表記
\xnn 16 進数表記
\cx コントロール文字 (x は ASCII 文字)
\C-x コントロール文字 (x は ASCII 文字)
\x 文字 x そのもの

長文!ヒアドキュメント


たとえば、HTMLのテンプレートな部分とか…
たとえば、メールの長い典型文とか…
そんな時はヒアドキュメント

STRING = <<"EOS"
これは
文字列です。
ボク永遠の#{age}歳!!
EOS

ちなみに、<<'EOS' ~ EOS と書けば、''囲みの文字列と同等の扱いになり、<<"EOS" ~ EOS と書けば、""囲みの文字列と同等の扱いになる。

ここから先の前提知識:ブロック


ブロックとは?
スコープの最小単位

do
  実行文
end
または
{
  実行文
}
{~}の方がdo~endより少しだけ優先度が高い

ブロック付きメソッド(いわゆるクロージャ)


使い方


def hoge(ary)
  ret = "result:"
  ary.each do |i|
    ret += i
  end
  return ret
end
または
def hoge(ary)
  ret = "result:"
  ary.each { |i|
    ret += i
  }
  return ret
end

  1. hogeメソッドからaryのeachを呼び出す
  2. eachメソッド内から、ブロックが呼ばれる
    1. |i|にeachからの引数(配列の内容)が渡る
    2. retに、渡された引数がどんどん連結される
  3. aryの内容をすべて連結した文字列を返す

イテレータ

10回ループを普通にやると
for i in [0..9] do
  p i
end

ブロック付きメソッドを使うと
[0..9].each do |i|
  p i
end

…あんまり変わらないかな?
でも、じつはこんなやり方も
10.times do |i|
  p i
end

for文より自然っぽくない?

open/close制御

ファイルを開いて閉じるを普通にやると
file = nil
begin
  file = File.open("hoge.txt")
  実行文
ensure
  file.close unless file == nil
end

ブロック付きメソッドを使うと
File.open("hoge.txt") do |file|
  実行文
end

何が便利かって、JavaやC#で起きがちな「クローズするためだけに延々とtry-finally記述が感染していく」がないこと!
例外ブロックも最適化できる!

ブロック付きメソッドの作り方


def hoge
  実行文
  yield
  実行文
end

引数があるときは
def hoge
  実行文
  yield(item)
  実行文
end

動性の高いRubyのリフレクション


リフレクションという認識すらないくらい、「普通のこと」になっている。
これもまた、動的言語で「すべてがオブジェクト」の世界観が成せる技。
次のような動的拡張が可能になっている。

既存のクラスにメソッドを拡張する


既存のArrayクラスにhogeというメソッドを追加する場合、次のように書けば良い。

class Array
  def hoge
  end
end

これ、なんと組み込みクラスにも可能。

もちろん、既存のメソッドを書き換えることも可能!

既存のオブジェクトにメソッドを拡張する


クラスにメソッドを拡張すると、なにかとメンドクサイ問題が出る場合がある。
そんな時は、対象となるオブジェクトにだけメソッドを拡張する。

array = []

def array.hoge
end

いちいち一個ずつメソッドを書き換えたり、メンドクサくない?って時にはMixIn


モジュールとは「機能的に同じものをまとめて定義しておく」機能のこと。
クラスとは違い、継承ができないし、インスタンスの生成もできない。
「GUIでのコントローラをモジュールで表現」のような使い方をする。
「そのクラスの直接的な機能じゃないけれど、副次的に必要になるユーティリティ的機能」などをモジュール化しておくと、なにかと便利。

module KeyNameListItem
  def value
    @name = '' unless defined? @name
    @key = @name unless defined? @key
    if (@key == @name)
      return @name
    end
    return "#{@key} - #{@name}" 
  end
  
  attr_reader :key
end

というモジュールをつくっておいて、GUIで「このクラスをリスト表示したい!」というときにさらっと

class Section
  include KeyNameListItem
end

というように、クラス再定義で組み込んでしまえる。

もちろん、オブジェクトにもMixIn


 section = Section.new
 
 section.extend KeyNameListItem

これらの再定義をうまく使っていくと、JavaやC#にありがちなXxxUtilとか、XxxHelperとかいったクラスが必要ないという事に気づくはず!



さあ!いま、Rubyという自由の羽を得た!!
飛び立とう!!
めくるめくオブジェクトの世界へ!!


最終更新:2010年01月25日 21:50