Подтвердить что ты не робот

Класс Ruby со статическим методом, вызывающим частный метод?

У меня есть класс с рядом статических методов. Каждый из них должен вызывать общий метод, но я стараюсь не выставлять этот последний метод. Сделать его закрытым только для доступа из собственного экземпляра класса? Защищенный, похоже, не может решить проблему здесь.

Как скрыть do_calc от вызова извне в статическом контексте? (Оставляя его доступным для вызова из первых двух статических методов.)

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

Ответ 1

Прежде всего, static на самом деле не является частью жаргона Ruby.

Возьмем простой пример:

class Bar
  def self.foo
  end
end

Он определяет метод foo для явного объекта self, который в этой области возвращает класс Bar. Да, его можно определить методом класса, но статический не имеет смысла в 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

Ответ 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