【问题标题】:How does one access protected class methods from instance methods in Ruby?如何从 Ruby 中的实例方法访问受保护的类方法?
【发布时间】:2011-12-20 14:47:57
【问题描述】:

我一定遗漏了人们在 Ruby 中是如何做到这一点的。

如果 '#protected' 未注释,我们会得到:
在“什么”中:为 Foo:Class (NoMethodError) 调用受保护的方法“zoop”

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

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'),但到目前为止,我似乎找不到一种优雅的方式。

【问题讨论】:

  • 是否存在一个基本假设,即类的实例应该比其他对象更亲密地访问类的单例方法?

标签: ruby class methods instance protected


【解决方案1】:

在 Ruby 中将方法设为私有或受保护几乎无关紧要,因为您只需调用 send() 即可绕过它们。

如果您希望 zoop 保持受保护,请像这样使用 send():

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

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2012-06-23
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 2013-04-06
      • 2014-05-01
      • 2020-04-23
      • 1970-01-01
      • 2020-07-26
      相关资源
      最近更新 更多