4

单例方法一定是公开的吗?如果没有,私有/受保护的单例方法何时有用?

4

4 回答 4

5

单例方法不一定需要公开。私有/受保护的单例方法在与常规私有/受保护方法相同的情况下很有用 - 例如,作为您不打算在类外调用的辅助方法。

class Foo
end

f = Foo.new

class << f
  def foo
    helper
    # other stuff
  end

  private
  def helper
  end
end
于 2015-01-28T23:23:55.327 回答
1

如果需要,您可以将单例方法设为私有:

class Foo

  def self.bar
    # ...
  end
  private_class_method :bar

end
于 2015-01-29T00:50:42.143 回答
1

如果需要,您可以将单例方法设为私有:

class Foo
end

f = Foo.new
def f.bar
  "baz"
end

f.singleton_class.send :private, :bar
f.bar # => NoMethodError: private method `bar' called for #<Foo:0x007f8674152a00>
f.send :bar # => "baz"

这是否真的有用取决于你在做什么。

于 2015-01-28T23:24:00.127 回答
0

它们有用吗?嗯。对于 Ruby 2.2

ObjectSpace.each_object(Module).flat_map { |m|
  m.singleton_class.private_methods(false) }.size
  #=> 900

大多数是类的单例类的私有方法:

ObjectSpace.each_object(Class).flat_map { |c|
  c.singleton_class.private_methods(false) }.size
  #=> 838

[编辑:以下是我原始帖子的编辑,以提供更多有用的信息。)

我对一件事感到困惑。让:

a = ObjectSpace.each_object(Class).map { |c|
      [c, c.singleton_class.private_methods(false)] }.to_h

b = ObjectSpace.each_object(Class).map { |c|
      [c, c.private_methods(false)] }.to_h

def diff(a,b) 
  a.map {|k,v| b.key?(k) ? [k,v-b[k]] : [k,v] }.reject { |_,a| a.empty?}.to_h
end

我预计diff(a,b) == diff(b,a) == {}。让我们来看看:

diff(a,b)
  #=> {} 

diff(b,a)
  #=> {Gem::Specification=>[:skip_during, :deprecate],
  #    Complex=>[:convert],
  #    Rational=>[:convert],
  #    Random=>[:state, :left],
  #    Time=>[:_load]} 

嗯。

于 2015-02-02T07:19:33.500 回答