Rubyチュートリアル 〜英文小説の最頻出ワードを見つけよう!(その5)

Rubyはユーザフレンドリです

Rubyにおいてオブジェクト指向はその基本的設計思想です
Ruby設計者まつもとゆきひろさん(愛称Matz)は
その思想を頑なに守りながら
一方でプログラマーの負担を最小化するために
ユーザインタフェースをよりフレンドリなものにしました
そのいくつかを紹介します

メソッド呼び出しのシンタックスシュガー

オブジェクト指向の基本ルールに従えば
簡単な算術演算も整数オブジェクトに対する
メソッド呼び出しのかたちを取ります

 6.+(2) # => 8
 6.-(2) # => 4
 6.*(2) # => 12
 6./(2) # => 3


しかしRubyでは慣れ親しんだ数学式の書き方ができます

 6 + 2 # => 8
 6 - 2 # => 4
 6 * 2 # => 12
 6 / 2 # => 3


オブジェクトの状態変数*1への代入も次のように自然に書けます

 charlie = Person.new('Charlie', 12, :male)
 charlie.age = 18 # => 18


このようなメソッド呼び出しのシンタックスシュガー(簡略表記)が
Rubyではできます

クラス定義およびレシーバの省略

Rubyではクラス定義をすることなく
コードを手続き型言語のように書くこともできます

 def fact(n)
   if n == 1
     1
   else
     n * fact(n-1)
   end
 end
 puts fact(10)
# >> 3628800


このようにいきなりメソッドfactを定義したり
レシーバを指定せずにputsメソッド呼んだりできます


でもここでもオブジェクト指向設計は崩れていません
Matzはオブジェクト内でのメソッド呼び出しを
そのレシーバを省略できるようにすると共に
クラスの外で書かれたコードが
Objectクラスという基本クラスに自動設定されるようにし
これによって設計の一貫性を維持しつつ
手続き型記述を許せるようにしたのです


Rubyの手続き型記述をよく使う方も
このことは頭の片隅にあって良いと思います
Rubyではクラスの外をトップレベルと呼ぶことがあります

変数・定数

以下の構文は変数carに対する値の代入ですが
Rubyではそれは正確な表現ではありません

 car = 'mini cooper'


「変数carで'mini cooper'文字列オブジェクトを
参照できるようにする」
と言ったほうがより正確です
つまり変数carは単なる参照ラベルに過ぎません
ですから
1つのオブジェクトに複数の変数を付けてもコピーは起きません
型といった概念もないので型宣言は不要です
Rubyでは次のコードは問題ありません

 a = 3
 b = 6
 c = a + b
 puts c
 a = 'mississippi'
 b = '-hippopotamus'
 c = a + b
 puts c
 # >> 9
 # >> mississippi-hippopotamus


’+’が算術演算子ではなくてメソッドであると前に書きました
前者のa + bは3整数オブジェクトに対して
6整数オブジェクトを引数に+メソッドを呼び出しています
その後a, bの参照先が変わって
後者のa + bは'mississippi'文字列オブジェクトに対して
'-hippopotamus'文字列オブジェクトを引数に
+メソッドを呼び出しています
つまり+メソッドは
異なるタイプのオブジェクトに送られているのです


そして整数オブジェクトでは+メソッドは
自身と引数を加算した整数オブジェクトを返すように
文字列オブジェクトでは自身と引数を連結した文字列オブジェクトを
返すようにそれぞれ定義されています


定数に対する考え方も同じです
定数は大文字で始まり貼り替えの必要のない
つまり内容が変化しないオブジェクトを指す目的で使います
なおクラス定義は大文字で始まりますが(String, Array)
これらはクラスオブジェクトを指し示す定数です

括弧の省略

Rubyでは解釈に曖昧さが生じない限り
括弧を省略できます

 def say word
   "#{word} " * 3
 end
 puts say "Hello!"
 puts say say "Hi!"
 # >> Hello! Hello! Hello! 
 # >> Hi! Hi! Hi!  Hi! Hi! Hi!  Hi! Hi! Hi!  


このオブジェクト原理主義的な書き方はこうです

 def say(word)
   "#{word} ".*(3)
 end
 puts(say("Hello!"))
 puts(say(say("Hi!")))
 # >> Hello! Hello! Hello! 
 # >> Hi! Hi! Hi!  Hi! Hi! Hi!  Hi! Hi! Hi!  


括弧の省略はこのようにコードの見た目を改善し読みやすくします
しかし行き過ぎはむしろコードを読み難くします
文章の句読点を使うように適度に括弧を使うのが常識人です

多重代入と*(アスタリスク)

Rubyでは関連する複数の変数に対して同時に代入ができます

 a, b, c = 0, 1, 2


これを多重代入といいます
もちろん関連がなくてもできますが推奨されません

 SIZE, name, switch = {:L => 'large', :M => 'medium', :S => 'small' }, 'Ruby',  [0, 1]


メソッドは複数の返り値を返せるので
これを多重代入で受けることもできます

 class Fixnum
   def plus_multi(other)
     return self + other, self * other
   end
 end
 
 a, b = 3.plus_multi 4
 puts a, b
 # >> 7
 # >> 12


変数に*(アスタリスク)を付けるとマルチラベルになって
受けたオブジェクトを配列に入れてそれを指します

 *a = 1, 2, 3
 p a
 # >> [1, 2, 3]


Rubyではこれをメソッドの引数にも使えるのです

 def hello(*a)
   a.each { |name| puts "Hello, #{name}!" }
 end
 
 hello 'donkey', 'alligator', 'hippopotamus'
 # >> Hello, donkey!
 # >> Hello, alligator!
 # >> Hello, hippopotamus!


このようにRubyは純粋なオブジェクト指向言語でありながら
とてもユーザフレンドリな作りになっています


呆れるほど長い前置きが続きました
でもこれで最初に掲げた4つの項目の説明は終わりです
もちろん説明はし尽くされていませんが
最初の目的を失しそうなのでここまでとします


そろそろ本題に入りましょう


(次回に続く)

*1:Rubyではインスタンス変数と呼びます