包括模块时避免类污染

时间:2017-06-22 16:32:49

标签: ruby

是否有一种简洁的方法来限制模块内的方法可见性,同时包含它?换句话说,我想限制使用仅在包含模块中使用的辅助方法来污染类。

module Bar
  def call
    hide_me
  end

  private

  # make this method only callable within this module
  def hide_me
    'visible'
  end
end

class Foo
  include Bar

  def unrelated_method
    hide_me
  end
end

# that's ok
Foo.new.call #=> 'visible'

# that's not
Foo.new.unrelated_method #=> 'visible'

我可以通过Bar.instance_method(:hide_me).bind(self).call调用它,我只是不想担心从某个模块访问或重新定义辅助方法。

2 个答案:

答案 0 :(得分:2)

您可以将类包装到模块中并在类中使用私有方法,如下所示:

module Bar

  def call
    BarClass.new.call
  end

  class BarClass
    def call
      hide_me
    end

    private 

    def hide_me
      puts "invisible"
    end

  end

end

class Foo

  include Bar

  def call_bar
    call
  end

  def this_method_fails
    hide_me
  end

end

答案 1 :(得分:0)

通过将模块包含在类中,然后取消定义不需要的包含方法,可以做到你想要的。

首先构建一个模块。

$cont = get-content "D:\path\file.csv" 
$cont | % {
$info = "^" + $_.Split("|")[0] + "^" + $_.Split("|")[1] + "^" + $_.Split("|")[2] + "^"
$info  
}

确认方法现在存在。

module M
  def cat
    puts "meow"
  end
  def dog
    puts "woof"
  end
  def owl
    puts "who?"
  end

  private

  def frog
    puts "ribbit"
  end
  def pig
    puts "oink"
  end
end

创建类,包括模块M.instance_methods(false) #=> [:cat, :dog, :owl] M.private_instance_methods(false) #=> [:frog, :pig]

M

检查实例方法。

class C
  def froggie
    frog
  end
  def cat
    puts "meow-meow"
  end
  include M
end

并确认C.instance_methods & [:cat, :dog, :owl, :froggie] #=> [:cat, :froggie, :dog, :owl] C.private_instance_methods & [:frog, :pig] #=> [:frog, :pig] :cat所有,而不是C

M

现在使用方法Module#undef_method从模块中取消定义不需要的方法。

C.instance_method(:cat).owner
  #=> C

需要class C [:cat, :owl, :pig].each { |m| undef_method(m) unless instance_method(m).owner == self } end 子句,以便unless...中定义的实例方法:cat未定义。

确认方法未定义。

C

执行方法。

C.instance_methods & [[:cat, :dog, :owl, :froggie]
  #=> [:cat, :froggie, :dog]
C.private_instance_methods & [:frog, :pig]
  #=> [:frog]
相关问题