【发布时间】:2012-07-19 15:34:09
【问题描述】:
我目前正在开发一个基本上执行另一个应用程序的框架,例如rails 在另一个 ruby 程序的上下文中。我最初的尝试只是像这样启动应用程序:
def load_app!
# Load the rails application
require './config/application'
# Initialize the rails application
@app = App::Application.initialize!
end
这里的问题是,框架的需求与加载的应用程序发生冲突,因此 initialize! 调用永远不会起作用,尽管它在普通的 ruby 程序中会起作用。
所以我的问题是,如果有人知道一种方法,可以基本上将此调用范围限定为一个行为类似于空白 RVM 环境的单元。所以基本上是这样的行为:
require 'json'
puts JSON.generate({:name => "test"})
blank_environment do
puts JSON.generate({:name => "test"})
#=> uninitialized constant JSON
require 'json'
puts JSON.generate({:name => "test"})
end
取消定义或卸载当前加载的常量并没有完成,因为我不知道所有这些常量,因为我再次使用具有其他依赖项的 gem。
那么有什么很酷的方法吗?或者任何其他方式来处理这个?
更新:
刚刚想到一个主意。为什么 ruby 的 require 方法总是需要全局范围?将加载的模块实际限定在当前模块下不是一个非常好的功能吗?
module ScopeA
require 'json' #> adds support for ScopeA::JSON
# due to normal ruby scoping everything can be called like normal in here
JSON.parse("something")
end
# JSON should not be available here
module ScopeB
require 'yaml'
YAML.parse("something") # but no JSON, of course
end
这样的东西不存在吗? include 已经知道常量了...
提前致谢!
【问题讨论】:
-
你不能使用相同版本的宝石吗?
-
不幸的是,该框架使用 goliath,它再次使用 async-rack - 这与默认的 rails rack gem 不兼容。而 rails
Bundler试图为 rails 提供必要的宝石,实际上这是正确的做法。 -
fork 一个新的 ruby 进程怎么样?
-
嗯,这确实有效,但前提是我 a) 在加载框架之前分叉它,因为所有资源都被复制到新进程中,并且 b) 我设置了某种 IPC 来与之交互。目前我正在尝试使用 dRb,但是对于这种问题来说,接缝有点沉重。一定有其他获得清洁环境的好方法,不是吗?
标签: ruby scope require execution