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

时间:2011-11-02 19:01:36

标签: ruby class methods instance protected

我一定不知道人们如何在Ruby中做到这一点。

如果取消注释'#protected',我们会得到:
在'what'中:受保护的方法'zoop'调用Foo:Class(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'),但到目前为止,我似乎无法找到一种优雅的方式。

2 个答案:

答案 0 :(得分:2)

将方法设置为私有或受Ruby保护几乎不重要,因为你可以调用send()来绕过它们。

如果您希望zoop保持受保护,请使用send(),如下所示:

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

答案 1 :(得分:2)

经过与rue:和drbrain的进一步讨论:在ruby-lang中,事实证明我通过在课堂上放置效用函数来节省内存的冲动是错误的。

在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