まえがき
4章 クラスとモジュール
4-1 クラス
4-1-2 インスタンスメソッド
疑問符付きのメソッド
真偽値を返すメソッドにつける。Javaでいう「is~」メソッドの代わり
感嘆符付きのメソッド
プログラマに対して注意を促したいメソッドにつける
# 疑問符付きのメソッド
puts 2.even? # true
str = 'abc'
# 破壊的でないメソッド
puts str.reverse # cba
puts str # abc
# 破壊的なメソッド
puts str.reverse! # cba
puts str # cba
4-1-8 特異メソッド
特定のインスタンスにだけメソッドを追加できる
class Foo
def override_me
puts 'in Foo class'
end
end
foo = Foo.new
bar = Foo.new
# barだけにメソッドを追加する
def bar.singleton_method
puts 'Called!!'
end
bar.singleton_method
puts '# barだけにメソッドを追加する'
begin
foo.singleton_method
rescue => e
puts "#{e.class}, #{e.message}"
end
puts '# 特異メソッド無いではsuperで元のクラスのメソッドを呼び出すことができる'
def foo.override_me
super
puts 'in singleton method'
end
foo.override_me
4-1-10 クラス定義のネスト
# JavaでいうInnerClassのような感じでクラス定義内に書く
class My
class SweetClass
end
end
# こういう風にも書ける
class My::SweetClass2
end
# 呼び出し方
my_sweet_class = My::SweetClass.new
my_sweet_class2 = My::SweetClass2.new
4-2 モジュール
4-2-1 モジュールの特徴
- インスタンスを生成することはできない
- 継承することはできない
モジュールの用途例
- 名前空間を作る
- モジュールのメソッドを、あるクラスのインスタンスメソッドとして取り込む
- モジュールのメソッドを、あるオブジェクトの特異メソッドとして取り込む
- モジュール関数を定義して使う
モジュールの特異メソッドを作成する
module Sweet
def self.lot
%w(brownie apple-pie bavarois pudding).sample
end
end
puts Sweet.lot
4-2-2 メソッドをクラスのインスタンスメソッドとして取り込む
こうすることでいわゆる「Mix-in(機能を他のクラスから集める)」を実現できる
module Greetable
def greet_to(name)
puts "Hello, #{name}. My name is #{self.class}"
end
end
class Alice
include Greetable
# moduleのメソッドをオーバーライドできる
def greet_to(name)
super
puts 'Nice to meet you!'
end
end
alice = Alice.new
alice.greet_to 'Bob'
# 代表的な組み込みモジュールEnumerableを組み込んだ例
class FriendList
include Enumerable
def initialize(*friends)
@friends = friends
end
def each
for v in @friends
yield v
end
end
end
friend_list = FriendList.new('Alice', 'Bob', 'Charlie')
puts friend_list.count # 3
puts friend_list.map{|v| v.upcase}.inspect # ["ALICE", "BOB", "CHARLIE"]
puts friend_list.find{|v| /b/ === v} # 'Bob'
4-2-3 メソッドをオブジェクトに取り込む
オブジェクトによって別の振る舞いを持たせることができる
module Destroyer
def introduce
super
puts 'I\'m destroyer.'
end
end
module Programmer
def introduce
super
puts 'I\'m programmer.'
end
end
class Person
def initialize(name)
@name = name
end
def introduce
puts "My name is #{@name}"
end
end
maruyama = Person.new('maruyama')
masudaK = Person.new('masudaK')
maruyama.extend Programmer
maruyama.introduce
masudaK.extend Destroyer
masudaK.introduce
4-2-4 モジュール関数
モジュール関数の良いところが分からない・・・
# モジュールから直接呼び出す
puts Math.sqrt(2) # 1.4142135623730951
# includeして使う
include Math
puts sqrt(2)
module MyFunctions
def my_module_function
puts 'Called!'
end
module_function :my_module_function
end
MyFunctions.my_module_function
課題
課題1
1-1. 以下の仕様を満たすswap(n1, n2)メソッドを、Arrayクラスのインスタンスの特異メソッドとして追加する
- 配列のn1番目の要素とn2番目の要素を交換した配列を返す(番目は0はじまり)
- 元の配列は破壊的に変更しない
- n1,n2が配列の要素数を超える、負の数の場合は何も起こらない
1-2. 以下の仕様を満たすswap!(n1, n2)メソッドを、Arrayクラスのインスタンスの特異メソッドとして追加する
- 元の配列のn1番目の要素とn2番目の要素を交換する(番目は0はじまり)
- n1,n2が配列の要素数を超える、負の数の場合は何も起こらない