🔀

ruby の delegate と Rails の delegate

に公開

ruby 提供の delegate と Rails 提供の delegate があって、機能はほぼ同じなのですが文法が異なります。

ruby の delegate

https://docs.ruby-lang.org/ja/latest/method/Forwardable/i/delegate.html

class Zap
   extend Forwardable
   delegate :length => :@str
   delegate [:first, :last] => :@arr
end

Rails の delegate

https://api.rubyonrails.org/classes/Module.html#method-i-delegate

class Zap < ActiveRecord::Base
  belongs_to :greeter
  delegate :hello, to: :greeter
end

rubocop-rails の Rails/Delegate

https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsdelegate

# bad
def bar
  foo.bar
end

# good
delegate :bar, to: :foo

rubocop-rails には delegate に書き換え可能なメソッド宣言に対する cop がありますが、これは(当然のことながら) Rails の delegate を想定した書き換えをします。実際にはどこかで extend Forwardable していたとしても rubocop の構文解析機能ではそれを検知するのは困難ですのでまあ仕方ないですね。で、この間違った cop 提案を受け入れると、ruby 側の delegate は to: という記法を認識できないので実行時エラーになります。 Syntax Error ではないので lint は通ってしまいますが、 rails zeitwerk:check すると class/module 宣言が一通り実行されるのでそこで落ちます。

Discussion