Как выполнить какую-либо процедуру во всех файлах ruby ​​в текущем каталоге? - PullRequest
0 голосов
/ 15 августа 2010

Я новичок в Ruby - у меня проблемы на каждом шагу ...

Представьте себе скрипт Ruby main.rb и множество неизвестных файлов сценариев script1.rb ... scriptN.rb .Каждый scriptX.rb содержит уникальный модуль, для которого необходимо выполнить одну процедуру:

Module X  
  def some_procedure(i)  
    puts "{#i} Module X procedure executed successfully!"  
  end  
end

Все, что мне нужно, это:

  1. перебирать все файлы втекущий каталог
  2. если текущий файл имеет имя типа /^script.*?\.rb$/
  3. , затем загрузите его и выполните some_procedure

Как я могу сделать это в main.rb?

Заранее спасибо!

Ответы [ 4 ]

1 голос
/ 15 августа 2010

Проблема может заключаться в том, что, когда файл требуется, он не возвращает список модулей (или, в общем, констант), который он определяет.Поэтому, если вы не знаете, какой модуль определен в сценарии, вы не будете знать, куда передать ваше сообщение some_procedure.

В качестве обходного пути, вы можете попробовать получить список определенных констант до и после того, как скрипт потребовался, найдите разность , то есть список констант во время require, и переберите через все из них, проверяя , который реализует метод, который вам нужен.

1 голос
/ 15 августа 2010

Выберите из этих замечательных ответов в SO при загрузке файлов: Лучший способ потребовать все файлы из каталога в ruby?

Затем в ваших файлах просто запустите их при загрузке, а не на вызов метода.

0 голосов
/ 17 августа 2010

Можно внести некоторые улучшения в предыдущее решение. Если мы хотим избежать специальных имен, мы можем использовать глобальный хеш для хранения имен процедур. Каждый загруженный файл script_xx.rb регистрирует свои собственные процедуры в этом глобальном хэше.

Обратите внимание, что в этом случае мы делаем два цикла:

  1. сначала мы загружаем все файлы script_xx.b

    каждый файл при загрузке регистрирует свои процедуры в массиве $ global_procs .

  2. итерация по всем записям в $ global_procs для выполнения всех зарегистрированных процедур с помощью eval ()

Надеюсь, это более "рубиновое" решение!

--- script_my1.rb

module My1  
  @value = 0  

  def self.some_procedure(i)  
    puts "#{i} my1 executed!"  
    @value = i  
  end  

  def self.another_procedure()  
    return @value  
  end  
end 

$global_procs << { 'module' => 'My1',
  'some_procedure' => 'My1.some_procedure',
  'another_procedure' => 'My1.another_procedure' }

--- script_my2.rb

module MMM2  
  @value = 0

  def self.some_procedure(i)  
    puts "#{i} MMM2 executed!"  
    @value = i  
  end  

  def self.another_procedure()  
    return @value  
  end  
end  

$global_procs << { 'module' => 'MMM2',
  'some_procedure' => 'MMM2.some_procedure',
  'another_procedure' => 'MMM2.another_procedure' }

--- main.rb

# Create global array for holding module's info
$global_procs = []

Dir['./script_*.rb'].each { |f|  
  next if File.directory?(f)  
  require (f)  
}

i = 1  
result = nil  

$global_procs.each { |p|
  puts "Module name: " + p['module']
  eval(p['some_procedure']+'(i)')
  result = eval(p['another_procedure']+'()')
  puts result  
  i = i + 1  
}
0 голосов
/ 15 августа 2010

Во-первых, нам нужно наложить некоторые ограничения:

  • Каждый файл script_my1.rb будет иметь модуль с именем Script_my1 .Т.е. первая буква заглавная, все остальные буквы - строчные.

Создайте два файла script_my1.rb и script_my2.rb следующим образом:

--- script_my1.rb :

module Script_my1  
  @value = 0  

  def self.some_procedure(i)  
    puts "#{i} my1 executed!"  
    @value = i  
  end  

  def self.another_procedure()  
    return @value  
  end  
end  

--- script_my2.rb :

module Script_my2  
  @value = 0

  def self.some_procedure(i)  
    puts "#{i} my2 executed!"  
    @value = i  
  end  

  def self.another_procedure()  
    return @value  
  end  
end  

Теперь основной скрипт,который загружает и выполняет some_procedure () в каждом модуле, а затем another_procedure () .

Обратите внимание, что каждый модуль может иметь отдельные переменные с одинаковыми именами @value.

Более того, я думаю, что каждый модуль может быть выполнен в отдельном потоке и иметь доступ к глобальным переменным, но я еще не проверял его.

-- main.rb :

# Load all files from the current directory  
# with name like script_xxx.rb  
i = 1  
result = nil  
Dir['./script_*.rb'].each { |f|  
  next if File.directory?(f)  

  require (f)  
  moduleName = f[2,f.length].rpartition('.rb')[0].capitalize  
  eval ( "#{moduleName}.some_procedure(%d)" % i )  
  eval ( "result = #{moduleName}.another_procedure()" )  
  puts result  
  i = i + 1  
}  

Вывод этой программы:

1 my1 executed!
1
2 my2 executed!
2

Вот и все!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...