Rails風味のRuby(その9)

WED(WeekEndDevelopers)のぽんたです。

開発スキルのないSIerからソフトウェアスキルを取得するため、WEDでモノづくりを計画しています。詳しい経緯はここ
※現在はruby on railsチュートリアル(ここから)を進めていってます。

最近railsの進捗がめっちゃ悪いです。。。少しずつですがなんとか進めていってます。。

継承は強力な概念ですが、もし仮に継承を使わずにpalindrome?メソッドをStringクラス自身に追加して(つまりStringクラスを拡張して)、より自然な方法で使えるとしたら、わざわざWordクラスを作らなくてもpalindrome?をリテラル文字列に対して直接実行できるようになるはずです。そんなことが可能なのでしょうか

?> "level".palindrome?
NoMethodError: undefined method `palindrome?' for "level":String
  from (irb):15

驚いたことに、Rubyでは組み込みの基本クラスの拡張が可能なのです。Ruby のクラスはオープンで変更可能であり、クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています。

?> class String
>>   # 文字列が回文であればtrueを返す
?>   def palindrome?
>>     self == self.reverse
>>   end
>> end
=> :palindrome?
?> "deified".palindrome?
=> true

例えば Web アプリケーションでは、変数が絶対に空白にならないようにしたくなることがよくあります (ユーザー名などはスペースやその他の空白文字になって欲しくないものです) ので、Railsはblank?メソッドをRuby に追加しています。 Railsの拡張は自動的にRailsコンソールにも取り込まれるので、次のようにコンソールで拡張の結果を確認できます

?> "".blank?
=> true
>> "      ".empty?
=> false
>> "      ".blank?
=> true
>> nil.blank?
=> true

演習1
palindrome?メソッドを使って、“racecar”が回文であり、“onomatopoeia”が回文でないことを確認してみてください。南インドの言葉「Malayalam」は回文でしょうか? ヒント: downcaseメソッドで小文字にすることを忘れないで。

?> class Word < String             # WordクラスはStringクラスを継承する
>>   # 文字列が回文であればtrueを返す
?>   def palindrome?
>>     self == self.reverse        # selfは文字列自身を表します
>>   end
>> end
=> :palindrome?
?> s = Word.new("racecar")
=> "racecar"
>> s.palindrome?
=> true

?> s = Word.new("onomatopoeia")
=> "onomatopoeia"
>> s.palindrome?
=> false

?> s = Word.new("Malayalam")
=> "Malayalam"
>> s.downcase.palindrome?
=> true

演習2
リスト 4.16を参考に、Stringクラスにshuffleメソッドを追加してみてください。ヒント: リスト 4.12も参考になります。

?> class String
>>   def shuffle
>>     self.split('').shuffle.join
>>   end
>> end
=> :shuffle
>> "foobar".shuffle
=> "booafr"

今回はここまで次回また続きをやっていきます^^