Lou*_*dox 13 ruby nokogiri google-drive-api
我正在寻找加载一些库,让他们做一些工作,然后做相反的事情require
以避免以后的兼容性错误.我不想转储到文件并重新启动shell,因为创建的对象(例如data
)可以由我的其他库很好地处理,只是不存在我想要卸载的早期文件.
有人有任何建议或知道这是否可行?2006年的一次谈话并没有得出多少结论,除了"看起来Webrick设法以某种方式做到这一点".
有问题的库是Google_drive和Nokogiri(电子表格处理库Roo依赖于Google_drive进行在线电子表格读/写,如该链接所述).
小智 11
尽管通常这么说,但可以使用此过程取消要求/卸载包。
d:/foo.rb
以下简单内容:class Foo
end
Run Code Online (Sandbox Code Playgroud)
irb(main):001:0> require 'd:/foo.rb'
=> true
irb(main):002:0> defined? Foo
=> "constant"
irb(main):003:0> Object.send(:remove_const, :Foo)
=> Foo
irb(main):004:0> defined? Foo
=> nil
Run Code Online (Sandbox Code Playgroud)
$"
,然后您需要从中清除您已经需要的文件:irb(main):005:0> $".select{|r| r.include? 'foo.rb'}
=> ["d:/foo.rb"]
irb(main):006:0> $".delete('d:/foo.rb')
=> "d:/foo.rb"
irb(main):007:0> $".select{|r| r.include? 'foo.rb'}
=> []
Run Code Online (Sandbox Code Playgroud)
irb(main):008:0> require 'd:/foo.rb'
=> true
irb(main):009:0> $".select{|r| r.include? 'foo.rb'}
=> ["d:/foo.rb"]
irb(main):010:0> defined? Foo
=> "constant"
irb(main):011:0> Foo.new
=> #<Foo:0x000000033ff8d8>
Run Code Online (Sandbox Code Playgroud)
Ric*_*ano 10
就像@Alex所说的那样,你可以使用它Kernel#fork
创建一个新的ruby进程,你可以require
在这里创建你的库.新的分叉进程将可以访问父进程中加载的数据:
def talk(msg)
# this will allow us to see which process is
# talking
puts "#{Process.pid}: #{msg}"
end
# this data was loaded on the parent process
# and will be use in the child (and in the parent)
this_is_data = ["a", "b", "c"]
talk "I'm the father process, and I see #{this_is_data}"
# this will create a new ruby process
fork{
talk "I'm another process, and I also see #{this_is_data}"
talk "But when I change `this_is_data`, a new copy of it is created"
this_is_data << "d"
talk "My own #{this_is_data}"
}
# let's wait and give a chance to the child process
# finishes before the parent
sleep 3
talk "Now, in the father again, data is: #{this_is_data}"
Run Code Online (Sandbox Code Playgroud)
执行的结果会因机器而异,Process.id
将返回不同的值,但它们将如下所示:
23520: I'm the father process, and I see ["a", "b", "c"]
23551: I'm another process, and I also see ["a", "b", "c"]
23551: But when I change `this_is_data`, a new copy of it is created
23551: My own ["a", "b", "c", "d"]
23520: Now, in the father again, data is: ["a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)
这很好!创建的每个进程fork
都是一个操作系统级进程,并在其自己的内存空间中运行.
你可以做的另一件事是以某种方式管理通过加载文件创建的全局变量,取而代之的是使用require
by load
.这种方法并没有解决已经指出的所有问题,但确实可以提供帮助.请参阅以下规格:
require "minitest/autorun"
describe "Loading files inside a scope" do
def create_lib_file(version)
libfile = <<CODE
class MyLibrary#{version}
VERSION = "0.0.#{version}"
end
class String
def omg_danger!
end
end
puts "loaded \#{MyLibrary#{version}::VERSION}"
CODE
File.write("my_library.rb", libfile)
end
after do
File.delete("my_library.rb") if File.exists?("my_library.rb")
end
describe "loading with require" do
it "sees the MyLibrary definition" do
create_lib_file("1")
require_relative "my_library.rb"
MyLibrary1::VERSION.must_be :==, "0.0.1"
"".respond_to?(:omg_danger!).must_be :==, true
end
end
describe "loading with #load " do
describe "without wrapping" do
it "sees the MyLibrary definition" do
create_lib_file("2")
load "my_library.rb"
MyLibrary2::VERSION.must_be :==, "0.0.2"
"".respond_to?(:omg_danger!).must_be :==, true
end
end
describe "using anonymous module wraping" do
it "doesn't sees MyLibrary definition" do
create_lib_file("3")
load "my_library.rb", true
->{ MyLibrary3 }.must_raise NameError
"".respond_to?(:omg_danger!).must_be :==, false
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
并执行结果:
Run options: --seed 16453
# Running tests:
loaded 0.0.3
.loaded 0.0.2
.loaded 0.0.1
.
Finished tests in 0.004707s, 637.3486 tests/s, 1274.6973 assertions/s.
3 tests, 6 assertions, 0 failures, 0 errors, 0 skips
Run Code Online (Sandbox Code Playgroud)
我不知道有什么方法可以卸载文件,但是你可以将精心挑选的全局变量重置为nil和undefine常量(足够接近):
class Foo; end
Object.constants.include?(:Foo)
Object.send(:remove_const, :Foo)
Object.constants.include?(:Foo)
Foo # NameError: uninitialized constant Foo
Run Code Online (Sandbox Code Playgroud)
根据您的冲突,您还可以临时重命名冲突的类:
Bar = Foo
Object.send(:remove_const, :Foo)
do_stuff
Foo = Bar
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6707 次 |
最近记录: |