LoginSignup
4
1

More than 5 years have passed since last update.

Rubyで「+ 1」と「+1」が違うとき

Last updated at Posted at 2019-02-26

ただのタイポによるエラーだったのだけど、「なんでArgumentError?」と考えてみたら面白かったのでメモ。

# Hogeクラスをつくって
class Hoge
  attr_accessor :count
end
hoge = Hoge.new

# hoge.countに値を入れる
hoge.count = 1
p hoge.count
# => 1

# hoge.countを1増やす
hoge.count = hoge.count + 1
p hoge.count
# => 2

# hoge.countをもう1増やそうと思うと
hoge.count = hoge.count +1
# => 3になる、と思いきやエラーになる
# ArgumentError:
#   wrong number of arguments (given 1, expected 0)

なぜかというと、1のコードは2のコードと同じ。

# 1
class Hoge
  attr_accessor :count
end

# 2
class Hoge
  def count
    @count
  end

  def count=(count)
    @count = count
  end
end

Rubyの場合、メソッドの引数は()に入れて渡すのだけれど、省略可能になっている。

hoge.count + 1
# => これはgetterのcountメソッドにアクセスして、その返り値に +1している
# 評価順はこう
# (hoge.count) + 1
hoge.count +1
# => この場合+1がgetterの引数になっている
# 評価順はこう
# hoge.count(+1)

+1の(スペースが間に入らない)場合、呼び出されるのはgetterのcountで、
getterは引数を取るよう定義されていないのでArgumentErrorが発生する。
だから、こうすれば通るけど、jsでよくかかれるような+=とは違う結果になる。

hoge.count = 1
hoge.count = +1
# => 1
# +1されて2が返るのではなく、何度やっても1が返る
hoge.count = +1
# => 1
4
1
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
4
1