ruby:如何在本地上下文中加载.rb文件

如何在Ruby中完成这个简单的任务?
我有一些简单的配置文件

=== config.rb config = { 'var' => 'val' } 

我想从main.rb文件中定义的某个方法加载配置文件,以便config.rb中的局部变量成为该方法的本地变量。
像这样的东西:

 === main.rb Class App def loader load('config.rb') # or smth like that p config['var'] # => "val" end end 

我知道我可以在config.rb使用全局变量然后在完成后config.rb定义它们,但我希望有一种ruby方式)

除了在受控环境中,我不建议这样做。

将模块保存到具有预定名称的文件,该文件定义了initializerun_it方法。 对于此示例,我使用test.rb作为文件名:

 module Test @@classvar = 'Hello' def initialize @who = 'me' end def get_who @who end def run_it print "#{@@classvar} #{get_who()}" end end 

然后编写一个简单的应用程序来加载并执行它:

 require 'test' class Foo include Test end END { Foo.new.run_it } # >> Hello me 

仅仅因为你可以做某事并不意味着你应该做。 我想不出我在制作中这样做的原因,只是把它作为一种好奇心和概念validation。 将这个提供给不知名的人将是一个很好的方法来让你的机器被黑客攻击,因为代码可以做任何拥有帐户可以做的事情。

配置文件。

 { 'var' => 'val' } 

加载配置文件

 class App def loader config = eval(File.open(File.expand_path('~/config.rb')).read) p config['var'] end end 

正如其他人所说,对于配置,最好使用YAML或JSON。 评估文件

binding.eval(File.open(File.expand_path('~/config.rb')).read, "config.rb") binding.eval(File.read(File.expand_path('~/config.rb')), "config.rb")

这种语法允许您在回溯中查看重要的文件名。 参见api docs [1]。

更新了eval命令以避免FD(文件描述符)泄漏。 我一定是在睡觉,或者可能应该在晚上的那个时候睡觉,而不是在stackoverflow上写。

[1] http://www.ruby-doc.org/core-1.9.3/Binding.html

你当然可以使用eval和File.read来解决一个解决方案,但事实上这很难,应该会给你一个信号,告诉你这不是解决你所遇问题的类似ruby的方法。 两种替代设计将使用yaml作为配置api,或定义一个简单的dsl。

YAML案例是最简单的,你在main.rb中只需要这样的东西:

 Class App def loader config = YAML.load('config.yml') p config['var'] # => "val" end end 

你的配置文件看起来像:

 --- var: val 

我只需要做一个类似的事情,因为我想能够加载一个“Ruby DLL”,它返回一个匿名类(一个事物的实例工厂)我创建它,它跟踪已经加载的项目,并允许加载的文件返回一个可以是任何东西的值 – 一个完全匿名的类,模块,数据等。它可以是一个模块,然后你可以在它加载后“包含”在一个对象中它可以提供一系列“属性”或方法。 您还可以添加“卸载”项以从加载的哈希中清除它并取消引用它加载的任何对象。

 module LoadableModule @@loadedByFile_ = {}; def self.load(fileName) fileName = File.expand_path(fileName); mod = @@loadedByFile_[fileName]; return mod if mod; begin Thread.current[:loadReturn] = nil; Kernel.load(fileName); mod = Thread.current[:loadReturn]; @@loadedByFile_[fileName] = mod if(mod); rescue => e puts(e); puts(e.backtrace); mod = nil; end Thread.current[:loadReturn] = nil; mod end def self.onLoaded(retVal) Thread.current[:loadReturn] = retVal; end end 

在加载的文件中:

 LoadableModule.onLoaded("a value to return from the loaded file");