20年Rubyを触ってきて初めて踏んだattr_readerのケツカンマ問題、あるいはdefの返り値がシンボルであることの問題

今日Rubyを書いていて、なんじゃこれと思った動作があった。

試しに以下のコードを実行してみて欲しい。

class Foo
  attr_reader :hoge, :fuga,

  def initialize(a, b)
    p a
    p b
  end
end

Foo.new

実行してみると分かるが、これには例外が出ない。

initializeで定義した必須引数はどうなったのか?

よくよく見るとattr_readerの引数の末尾に,がある。

つまり、このコードは分かりやすく書くと以下の様になる。

class Foo
  attr_reader(:hoge, :fuga, def initialize(a, b)
      p a
      p b
  end)
end

Foo.new

このコードを更に分かり易く書くとこうなる。

class Foo
  def initialize(a, b)
    p a
    p b
  end

  attr_reader :hoge, :fuga, :initialize
end


Foo.new

initializeが定義され次の瞬間にattr_readerで上書きされてdef initialize; @initialize; end相当の状態になる。

そりゃそうだという感じだし、何もおかしなことはない。ないのだが!これは結構怖い。

という訳で、attr_なんちゃらの引数のケツカンマには気を付けよう。 (というかシンボルを受け取ってメソッドを定義する類のメタプロコード全般)

自分で書く分には意外とこうはならないのだが、copilotみたいな奴の補完でざっくりと書いてしまうと、ケツカンマ以外は問題無い上にシンタックスエラーも出ないので、「はあ?!」という動きになってしまう。というかなった。