Chr*_*son 6 ruby oop encapsulation module ruby-on-rails
我希望能够在模块中使用包含该模块的类无法访问的方法.给出以下示例:
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
Run Code Online (Sandbox Code Playgroud)
我希望Foo.new.do_stuff爆炸,因为它试图访问模块试图隐藏它的方法.但是,在上面的代码中,Foo.new.do_stuff可以正常工作:(
有没有办法在Ruby中实现我想做的事情?
更新 - 真正的代码
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
Run Code Online (Sandbox Code Playgroud)
很明显,这段代码被黑了,并且由于一些严重的重构,我的问题的目的是找出是否有一种方法可以重构这个模块,而不会因为意外覆盖ActiveRecord :: Base或其他任何模块中包含的任何其他模块而不受惩罚. Place.rb.
我不相信有任何直接的方法来做到这一点,这是设计的.如果需要封装行为,则可能需要类,而不是模块.
在Ruby中,私有方法和公共方法之间的主要区别是私有方法只能在没有显式接收器的情况下调用.调用MyObject.new.my_private_method将导致错误,但my_private_method在方法定义中调用MyObject将正常工作.
将模块混合到类中时,该模块的方法将"复制"到类中:
[I]如果我们在类定义中包含一个模块,它的方法可以有效地附加到类中,或者"混入"到类中.- Ruby用户指南
就课程而言,该模块不再作为外部实体存在(但请参阅Marc Talbot在下面的评论).您可以在类中调用任何模块的方法而无需指定接收器,因此它们实际上不再是模块的"私有"方法,只是类的私有方法.
| 归档时间: |
|
| 查看次数: |
4060 次 |
| 最近记录: |