Как инкапсулировать методы включенных модулей в Ruby?

Я хочу иметь возможность иметь в модуле методы, недоступные классу, который включает модуль. Приведем следующий пример:

class Foo
  include Bar

  def do_stuff
    common_method_name
  end
end

module Bar
  def do_stuff
    common_method_name
  end

  private
  def common_method_name
    #blah blah
  end
end

Я хочу, чтобы Foo.new.do_stuff взорвался, потому что он пытается получить доступ к методу, который модуль пытается скрыть от него. Однако в приведенном выше коде Foo.new.do_stuff будет работать нормально :(

Есть ли способ достичь того, что я хочу сделать в Ruby?

UPDATE - Реальный код

class Place < ActiveRecord::Base
  include RecursiveTreeQueries

  belongs_to :parent, {:class_name => "Place"}
  has_many :children, {:class_name => 'Place', :foreign_key => "parent_id"}
end


module RecursiveTreeQueries

  def self_and_descendants
     model_table = self.class.arel_table
     temp_table = Arel::Table.new :temp
     r = Arel::SelectManager.new(self.class.arel_engine).from(model_table).project(model_table.columns).join(temp_table).on('true').where(model_table[:parent_id].eq(temp_table[:id]))
     nr = Place.scoped.where(:id => id)
     q = Arel::SelectManager.new(self.class.arel_engine)
     as = Arel::Nodes::As.new temp_table, nr.union(r)
     arel = Arel::SelectManager.new(self.class.arel_engine).with(:recursive,as).from(temp_table).project(temp_table[:id])
     self.class.where(model_table[:id].in(arel))
   end  

  def self_and_ascendants
    model_table = self.class.arel_table
    temp_table = Arel::Table.new :temp
    r = Arel::SelectManager.new(self.class.arel_engine).from(model_table).project(model_table.columns).join(temp_table).on('true').where(temp_table[:parent_id].eq(model_table[:id]))
    nr = Place.scoped.where(:id => id)
    q = Arel::SelectManager.new(self.class.arel_engine)
    as = Arel::Nodes::As.new temp_table, nr.union(r)
    arel = Arel::SelectManager.new(self.class.arel_engine).with(:recursive,as).from(temp_table).project(temp_table[:id])
    self.class.where(model_table[:id].in(arel))
 end

end

Очевидно, что этот код взломан и нуждается в серьезном рефакторинге, и цель моего вопроса - выяснить, есть ли способ рефакторить этот модуль так, чтобы я не мог случайно перезаписать какой-нибудь метод ActiveRecord::Base или любого другого модуля, включенного в Place.rb.

6
задан Chris Aitchison 22 February 2012 в 05:58
поделиться