如何在当前目录中的所有ruby文件中执行某些过程?

时间:2010-08-15 14:12:06

标签: ruby file

我是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
  4. 我如何在 main.rb

    中执行此操作

    提前谢谢!

4 个答案:

答案 0 :(得分:1)

在加载文件时,在SO中选择这些优秀答案:Best way to require all files from a directory in ruby?

然后在你的文件中,让它们在加载时执行,而不是在方法调用上执行。

答案 1 :(得分:1)

问题可能是,当需要文件时,它不会返回它定义的模块列表(或者,通常是常量)。因此,除非您不知道脚本定义了哪个模块,否则您将无法知道将some_procedure消息传递到何处。

作为一种变通方法,您可以在需要脚本之前和之后尝试getting the list定义的常量,找到difference,即require期间的常量列表,以及{{3}通过所有这些,检查iterate您需要的方法。

答案 2 :(得分:0)

首先,我们需要设置一些限制:

  • 每个文件 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

就是这样!

答案 3 :(得分:0)

可以对先前的解决方案进行一些改进。如果我们想避免特殊命名,我们可以使用全局哈希来存储过程的名称。每个加载的 script_xx.rb 文件都会在此全局哈希中注册它自己的过程。

请注意,在这种情况下,我们进行两个周期:

  1. 首先我们加载所有文件 script_xx.b

    加载时的每个文件都会在 $ global_procs 数组中注册它的程序。

  2. 然后遍历 $ global_procs 中的所有条目,通过 eval()

  3. 执行所有已注册的程序

    希望,这是一个更像'类似红宝石'的解决方案!

    --- <强> 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  
    }