Ruby — Как создать переменные класса для доступа в функции

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

Я хочу создать функцию для установки переменной экземпляра, например attr_reader

 class Base
    def exec
       # get all functions to check
       # if all functions return true
       # I will do something here
    end
end
 

И тогда у меня есть класс inherit Base .

 class SomeClass < Base
  check :check_1
  check :check_2

  def check_1
   # checking
  end

  def check_2
   # checking
  end
end

class Some2Class < Base
  check :check_3
  check :check_4
  
  def check_3
   # checking
  end

  def check_4
   # checking
  end
end
 

Поскольку мне нужна только 1 логика для выполнения во всех классах, но у меня много разных проверок для каждого класса, мне нужно делать это гибко.

Пожалуйста, дайте мне ключевое слово для этого.

Большое спасибо.

Ответ №1:

Для того, чтобы иметь check :check_1 , вам нужно определить check как метод класса:

 class Base
  def self.check(name)
    # ...
  end
end
 

Поскольку вы хотите вызвать переданные имена методов позже, я бы сохранил их в массиве: (предоставляется другим методом класса checks )

 class Base
  def self.checks
    @checks ||= []
  end

  def self.check(name)
    checks << name
  end
end
 

Это уже дает вам:

 SomeClass.checks
#=> [:check_1, :check_2]

Some2Class.checks
#=> [:check_3, :check_4]
 

Теперь вы можете перемещаться по этому массиву изнутри exec и вызывать каждый метод через send . Вы можете использовать all? , чтобы проверить, все ли они возвращают правдивый результат:

 class Base
  # ...

  def exec
    if self.class.checks.all? { |name| send(name) }
      # do something
    end
  end
end

SomeClass.new.exec # doesn't do anything yet
 

Эта self.class часть необходима, потому что вы вызываете метод класса checks из метода экземпляра exec .

Комментарии:

1. спасибо @stefan. Я нашел то, что хочу. Я использовал class_variables для этого

2. @tai.groddy обратите внимание, что переменная класса (with @@ ) является общей для класса и его подклассов. Вероятно, вы хотите иметь переменную экземпляра класса @ как показано выше), чтобы каждый подкласс мог иметь свой собственный массив.