如何在Ruby的实例方法中访问受保护的类方法?

6

我可能对Ruby中人们如何做这件事有所遗漏。

如果取消'#protected'的注释,我们会得到:
在'what'方法中:调用了Foo类的受保护方法'zoop'(NoMethodError)

是否有更好的方法来处理受保护的类方法?

class Foo
  class << self
    #protected
    def zoop 
      "zoop"
    end
  end
  public
  def what
    "it is '#{self.class.zoop}'"
  end
  protected
end

a = Foo.new
p a.what # => "it is 'zoop'"

我希望zoop被保护或私有化(不允许调用“Foo.zoop”),但目前似乎找不到优雅的方法。


一个类的实例是否应该比其他对象更加密切地访问该类的单例方法,这里有一个基本的假设吗? - Andrew Grimm
2个回答

2
在与ruby-lang中的rue和drbrain进一步讨论后,我发现将实用函数放置在类级别以节省内存的冲动是错误的。在Ruby中,实例方法已经挂在类上,答案是继续将实用函数放置在实例级别作为私有函数。总之,只由实例方法访问的实用函数:
class Foo
  def what
    "it is '#{zoop}'"
  end
  private
  def zoop
    "zoop"
  end
end

p Foo.new.what # => "it is 'zoop'"

对于需要从实例方法和类方法调用的实用函数,嵌套模块似乎是一种流行的方法:

class Foo
  module Util
    def self.zoop
      "zoop"
    end
  end
  def what
    "it is '#{Util.zoop}'"
  end
  class << self
    def class_what
      "for all time it is '#{Util.zoop}'"
    end
  end
end

p Foo.new.what   # => "it is 'zoop'"
p Foo.class_what # => "for all time it is 'zoop'"
p Foo::Util.zoop # visible, alas

2

在Ruby中,将方法设为私有或受保护几乎没有意义,因为您可以使用send()绕过它们。

如果您想让zoop保持受保护状态,请像这样使用send():

def what
  "it is '#{self.class.send(:zoop)}'"
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接