ただのタイポによるエラーだったのだけど、「なんで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