Сделайте ClassMethods также доступными в виде функции модуля с помощью ActiveSupport::Concern.

Учитывая следующий код:

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def foo
      puts 'foo'
    end
  end
end

class Bar
  include Foo
end

Что я хотел бы сделать, так это вызвать Foo.foo вместо Bar.foo. Иногда кажется более естественным вызвать метод класса в исходном модуле, особенно когда функциональность не имеет ничего общего с включенным классом и лучше описана вместе с именем исходного модуля.


person kenn    schedule 08.07.2011    source источник


Ответы (1)


Это похоже на запах кода. Сказав это, вы можете просто расширить модуль Foo с помощью методов класса:

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def foo
      puts 'foo'
    end
  end

  extend ClassMethods
end

class Bar
  include Foo
end

Bar.foo
Foo.foo
person Peter Brown    schedule 08.07.2011
comment
Это отлично работает, спасибо! Кстати, почему вы думаете, что код пахнет? - person kenn; 08.07.2011
comment
Наличие модуля, расширяющего себя из модуля, который определен как методы его класса, просто не кажется правильным. Обычно, если вы хотите получить доступ к методу foo из Foo, вы просто делаете Foo::ClassMethods.foo. В этом нет ничего плохого, но я никогда раньше не видел такого шаблона и не рекомендовал бы привыкать к нему. - person Peter Brown; 08.07.2011
comment
@Beerlington: Вы уверены, что это работает Foo::ClassMethods.foo в первом примере? Я только что проверил, и это не так (Ruby v2.0). Спасибо. - person sequielo; 14.03.2014