はじめに
-
Ruby
では+
演算子をはじめ、様々な演算子が再定義可能 -
1+2
の結果が100
なんていうめちゃくちゃな定義も可能
コード
new_plus_operand.rb
class MyString
# インスタンス変数valueにアクセスできるようにする
attr_accessor :value
# コンストラクタ
def initialize(new = 'sample')
@value = new
end
# +演算子の再定義
def +(target)
# targetがMyStringクラスでなければエラーを返す
return 'error' unless target.is_a?(MyString)
# この+演算子を使用するとviaが付くようになる
"#{@value}#{target.value} via new plus operand"
end
end
# 普通のStringクラスの+演算子
puts '普通の文字列結合'
a = 'aaa'
b = 'bbb'
p a+b
puts
# 新しく定義したMyStringクラスの+演算子
c = MyString.new('ccc')
d = MyString.new('ddd')
e = MyString.new()
puts '各オブジェクトの中身を確認'
p c.value
p d.value
p e.value
puts '新しく定義した文字列結合'
p c+'a'
p c+1
p c+d
p c+e
結果
普通の文字列結合
"aaabbb"
各オブジェクトの中身を確認
"ccc"
"ddd"
"sample"
新しく定義した文字列結合
"error"
"error"
"cccddd via new plus operand"
"cccsample via new plus operand"
問題1
1+1の時だけ100になるように+演算子を再定義してみましょう。
新しくMyFixnumを定義しても良いしFixnum自体を上書きしても良い。
問題2
+演算子を再定義して加算の結果が3の倍数と3の数字がつく時だけアホ
を返すようにしてみましょう。
10+1 => 11
10+2 => 'アホ'
10+3 => 'アホ'
10+4 => 14
10+5 => 'アホ'
おわりに
今回は新しくMyStringという新しいクラスを定義してそこの演算子を定義しましたがStringクラスの+演算子を再定義することも可能です。
根本の動きから変更してしまうので十分注意して使用するべし。
Appendix
私が問題を解いたものを解答例として載せる
問題1解答例
class Fixnum
# +演算子を再定義する前に後で使用するために保持しておく
alias_method :old_add, :+
def +(target)
return 100 if(self == 1 && target == 1)
self.old_add(target)
end
end
p 1+0
p 1+1
p 1+2
p 1+3
結果
1
100
3
4
問題2解答例
class Fixnum
# +演算子を再定義する前に後で使用するために保持しておく
alias_method :old_add, :+
def +(target)
result = self.old_add(target)
# 3の倍数か3が含まれている時
if(result % 3 == 0 || result.to_s.include?('3'))
return 'アホ'
else
return result
end
end
end
10.times do |i|
p 10+i
end
結果
10
11
"アホ"
"アホ"
14
"アホ"
16
17
"アホ