Вызов методов класса из модуля, включенного этим классом в Ruby - PullRequest
2 голосов
/ 06 января 2012

В приведенном ниже коде я хотел бы вызвать метод класса done класса, который включает в себя модуль изнутри self.hello

Объяснение:

A::bonjour вызоветMod::hello так же будет B::ciao

Я хотел бы иметь возможность обнаруживать «вызывающий класс» (A или B) в Mod::hello, чтобы иметь возможность вызывать A::done или B::done

module Mod
 def self.hello
  puts "saying hello..."
 end
end

class A
 include Mod

 def self.bonjour
  Mod::hello 
 end

 def self.done
  puts "fini"
 end
end

class B
 include Mod

 def self.ciao
  Mod::hello
 end

 def self.done
  puts "finitto"
 end
end

1 Ответ

4 голосов
/ 06 января 2012

Хотя (возможно) не так чисто, как ответ Никласа, это все же легко выполнимо, и IMO чище, чем шаблон использования, показанный в ОП, который основан на знании, в какой модуль смешан.

(я предпочитаюне нужно передавать аргумент таким смешанным методам, когда существуют другие средства.)

Вывод:

pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto

Смелость:

module Mod
  module ClassMethods
    def hello
      puts "saying hello..."
      done
    end
  end

  def self.included(clazz)
    clazz.extend ClassMethods
  end
end

Модифицированный классдекларации, удалив явную ссылку на модуль:

class A
  include Mod

  def self.bonjour
    hello
  end

  def self.done
    puts "fini"
  end
end

class B
  include Mod

  def self.ciao
    hello
  end

  def self.done
    puts "finitto"
  end
end

Вы также можете предоставить реализацию по умолчанию done:

module Mod
  module ModMethods
    def hello
      puts "saying hello..."
      done
    end

    def done
      throw "Missing implementation of 'done'"
    end
  end

  def self.included(clazz)
    clazz.extend ModMethods
  end
end

Как указано в комментарии к этому сообщению,если фрагмент в OP является точным представлением фактического варианта использования, вы можете также использовать extend (вместо include), оставляя все более чистым:

module Mod
  def hello
    puts "saying hello..."
    done
  end

  def done
    raise NotImplementError("Missing implementation of 'done'")
  end
end

И классы, использующие extend:

class A
  extend Mod

  def self.bonjour
    hello
  end

  def self.done
    puts "fini"
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...