LoginSignup
5
6

More than 5 years have passed since last update.

Rubyで+演算子を再定義する

Posted at

はじめに

  • 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
"アホ
5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6