Quiero poder tener métodos en un módulo que no sean accesibles para la clase que incluye el módulo. Teniendo en cuenta el siguiente ejemplo:¿Cómo encapsulo los métodos de módulo incluidos en 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
Quiero Foo.new.do_stuff para hacer estallar, ya que está intentando acceder a un método que el módulo está tratando de esconderse de ella. En el código anterior, sin embargo, Foo.new.do_stuff trabajará muy bien :(
¿Hay una manera de lograr lo que quiero hacer en Ruby
ACTUALIZACIÓN -? El código real
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
Está claro que este código está bloqueado y debido a una seria refactorización, y el propósito de mi pregunta es averiguar si hay alguna manera de refactorizar este módulo impunemente al sobrescribir accidentalmente algún método en ActiveRecord :: Base o cualquier otro módulo incluido en Place.rb.
En cuanto al primer ejemplo, 'Bar # do_stuff' es esencialmente una interfaz pública para' common_method_name', por lo que no hay ninguna lógica de que el código se rompa. Debería romperse en caso de que haga 'Foo.new.common_method_name'. –