Как я могу объявить метод mixin таким образом, чтобы его можно было использовать как из методов экземпляра, так и из методов класса? - PullRequest
2 голосов
/ 26 ноября 2011

Я хочу поместить метод в модуль Ruby таким образом, чтобы его можно было вызывать из метода класса или метода экземпляра, используя простой синтаксис:

module MyMod
  def fmt *args
    args.map { | a | "You said #{a}" }
  end
end

class MyClass
  include MyMod
  def inst
    puts fmt 1,2,3
  end
  def self.cls
    puts fmt 4,5,6
  end
end

.не работает, потому что метод класса (cls) не может видеть метод экземпляра fmt.Если я изменю определение на self.fmt, то метод экземпляра должен вызвать его как MyMod.fmt.

Я бы хотел просто вызывать fmt (some stuff) из обоих типов методов.Есть ли "рубиновый" способ сделать это?Я могу определить модуль как

module MyMod
  def self.fmt *args
    args.map { | a | "You said #{a}" }
  end
  def fmt *args
    MyMod.fmt args
  end
end

, но это не СУХО, не так ли?Есть ли более простой способ?

Ответы [ 2 ]

5 голосов
/ 26 ноября 2011

Вы можете использовать преимущество метода Module#included, чтобы сделать это так:

module MyMod
  # here base is a class the module is included into
  def self.included(base)
    # extend includes all methods of the module as class methods
    # into the target class
    base.extend self
  end

  def fmt(*args)
    args.map { |a| "You said #{a}" }
  end
end

class MyClass
  # regular include provides us with instance methods
  # and defined above MyMod#included hook - with class methods
  include MyMod

  def inst
    puts fmt(1, 2, 3)
  end

  def self.cls
    puts fmt(4, 5, 6)
  end
end

puts MyClass.cls
puts MyClass.new.inst

А вот и вывод:

You said 4
You said 5
You said 6

You said 1
You said 2
You said 3

Для более подробного объяснения смотрите эту статью .

1 голос
/ 26 ноября 2011

И include, и extend модуль MyMod в MyClass, так что метод fmt добавляется как * экземпляр класса и метод класса в MyClass.

Что делает Object#extend, так это добавляет методы модуля к одному экземпляру. В данном случае этим экземпляром является сам класс, поэтому методы будут доступны как методы класса.

...