【问题标题】:Ruby class with static method calling a private method?带有调用私有方法的静态方法的Ruby类?
【发布时间】:2015-06-26 13:28:46
【问题描述】:

我有一个包含许多静态方法的类。每个人都必须调用一个通用方法,但我尽量不公开后一种方法。将其设为私有只会允许从自己的类实例进行访问?受保护似乎也不能解决这里的问题。

如何在静态上下文中隐藏 do_calc 以免被外部调用? (让它可以从前两个静态方法中调用。)

class Foo
  def self.bar
    do_calc()
  end
  def self.baz
    do_calc()
  end
  def self.do_calc
  end
end

【问题讨论】:

  • 你有什么问题?
  • 为什么self.bar调用带括号的方法而self.baz不调用?
  • 我认为private_class_method 可以满足您的要求。

标签: ruby static encapsulation


【解决方案1】:

首先,static 并不是真正的 Ruby 行话的一部分。

我们举个简单的例子:

class Bar
  def self.foo
  end
end

它在显式对象self 上定义了方法foo,该方法在该范围内返回包含类Bar。 是的,可以定义一个类方法,但是static在Ruby中并没有什么意义。

那么private 将不起作用,因为在显式对象(例如def self.foo)上定义方法会绕过访问限定符并将方法公开。

你可以做的是,使用class << self语法打开包含类的元类,并将那里的方法定义为实例方法:

class Foo
  class << self

    def bar
      do_calc
    end

    def baz
      do_calc
    end

    private

    def do_calc
      puts "calculating..."
    end
  end
end

这将为您提供所需的:

Foo.bar
calculating...

Foo.baz
calculating...

Foo.do_calc
NoMethodError: private method `do_calc' called for Foo:Class

【讨论】:

  • 而且lingo这个词也不是每个人的词汇的一部分;)
【解决方案2】:

您可以像这样使用private_class_method 定义一个私有类方法:

class Foo
  def self.bar
    do_calc
  end

  def self.baz
    do_calc
  end

  def self.do_calc
    #...
  end
  private_class_method :do_calc
end

【讨论】:

    【解决方案3】:

    或从 Ruby 2.1 开始:

    class Foo
      def self.bar
        do_calc
      end
    
      private_class_method def self.do_calc
        #...
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 2017-05-23
      • 2019-07-26
      • 1970-01-01
      • 2013-09-25
      • 2012-07-14
      • 2016-01-05
      • 1970-01-01
      • 2022-11-20
      相关资源
      最近更新 更多