Непредвиденный результат при вызове метода instance_methods привел к возвращению пустого массива

Пожалуйста, рассмотрите приведенный ниже код

class Execute
  def self.inherited(klass)
    puts "Class Inherited: #{klass}"
    klass.run
  end

  def self.run
    puts "Running Instance Methods"
    instance_methods(false).each do |m|
      if m.to_s.start_with?("test_")
        puts "Executing Method: #{m}"
        new.send(m)
      end
    end
  end
end

puts "Before class definition"

class Raja < Execute
  def test_1
    puts 'test_1'
  end

  def test_2
    puts 'test_2'
  end

  def test_3
    puts 'test_3'
  end
end

puts "After class definition"

В настоящее время я пытаюсь получить доступ к методам test_1, test_2 и test_3, создавая экземпляр объекта из родительского класса. Изучив программу, можно понять действия, которые я выполняю. Тем не менее проблема возникает, поскольку вызов метода instance_methods возвращает пустой массив, в отличие от его ожидаемого поведения при предоставлении имен методов экземпляра, т. е. test_1, test_2 и test_3. Я не понимаю, почему это несоответствие происходит, и был бы очень признателен за любую помощь в решении этой проблемы.

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
0
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Class#inherited вызывается в момент наследования. На данный момент никакие instance_methods (методы экземпляра, не унаследованные с тех пор, как вы использовали false) не определены.

class Raja < Execute #inherited is called here 
 # methods are defined here
end

Это будет похоже на следующее

class Raja;end 
Raja.instance_methods(false) #=> []
class Raja
  def test_1 = 'test1'
end

Вместо этого вы могли бы заглянуть в Module#method_added, однако мне неясно, в чем причина этого кода, поэтому все, что я могу сделать, это ответить на вопрос, почему вы испытываете то, что испытываете.

Обновлять Основываясь на комментариях OP, ищущих механизм автозапуска, похожий на test-unit:

В качестве очень упрощенного примера:

class Tracker
  @@runner = {} 
  def self.runner
    @@runner
  end 
  def self.inherited(klass) 
    runner[klass] = [] 
  end 
  def self.method_added(method_name)
    runner[self] << method_name if method_name.match?(/test_/)
  end 
end 

class Runner 
 def self.run
    Tracker.runner.each do |klass,tests|
      tests.each do |m| 
        klass.new.send(m)
      end 
    end 
  end
end 
# Run the Runner before the program exits
at_exit { Runner.run}

Затем (foo.rb)

require 'runner_tracker'
class Foo < Tracker 
  def test_1
    puts 'test_1'
  end

  def test_2
    puts 'test_2'
  end

  def test_3
    puts 'test_3'
  end
end 

Выход

> ruby foo.rb
test_1
test_2
test_3

Вы объясняете, почему так. Но моя цель — вызвать метод, который начинается с «test_», когда я запускаю вышеуказанную программу. Такая конфигурация доступна, когда мы наследуем Test::Unit::TestCase в нашем классе. Поэтому я хочу знать, как они этого добились. Его жемчужина под названием test-unit предоставляет эту возможность.

Rajagopalan 10.02.2023 19:46

@Rajagopalan Я объяснил, почему, потому что это то, о чем вы просили. Библиотека, на которую вы ссылаетесь, намного сложнее, чем ваш пример, и не имеет абсолютно ничего общего с унаследованным хуком, кроме отслеживания потомков класса Test::Unit::TestCase, и, как я уже упоминал, сильно использует method_added, но даже это не то, что на самом деле «работает». " код...

engineersmnky 10.02.2023 20:22

Эй, я видел вашу отредактированную программу, вы на самом деле более или менее достигли того, о чем я просил, за исключением одного. В Test::Unit::TestCase наследования этого Test::Unit::TestCase достаточно, нам не нужно вызывать что-то вроде Runner.run. Кроме этого, вы добились всего, отлично. Спасибо.

Rajagopalan 11.02.2023 04:56

Большое спасибо. Это то, чего я хочу достичь.

Rajagopalan 11.02.2023 06:42

Другие вопросы по теме