dee*_*pak 5 ruby rubygems require
如果找不到库(通过 require 加载),我可以有条件地跳过在同一文件中加载“更多”ruby 代码吗?
begin
require 'aws-sdk'
rescue LoadError
puts "aws-sdk gem not found"
return #does not work. nor does next
end
# code after here should not be executed as `aws-sdk` gem was not found
puts "=== should not get executed"
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我可以要求 Ruby 在点击 rescue LoadError.
类似于提前返回,但用于加载文件而不是函数。
需要它,因为我有一个需要aws-sdkrubygem 的 rake 任务,但我仅在本地计算机上使用它。如果aws-sdk找不到,那么我之后在同一个文件中加载代码就没有意义。我想我可以将代码分割成更小的文件并在 require 调用中扭曲它
if Rails.env.development?
require 'import_to_heroku'
end
Run Code Online (Sandbox Code Playgroud)
但不想扭曲或修改我现有的代码
另外,我可以将整个代码包装在条件中,但这是不优雅的。开始救援块也是显式控制流的一种形式。我不想以任何方式包装或触摸原始代码
也许是一个 api,比如
require_or_skip_further_loading 'aws-ruby`
Run Code Online (Sandbox Code Playgroud)
所以我希望我的代码在功能上等同于
begin
require 'aws-sdk'
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
rescue LoadError
puts "aws-sdk gem not found"
end
Run Code Online (Sandbox Code Playgroud)
或者通过 if 条件
library_found = false
begin
require 'aws-sdk'
library_found = true
rescue LoadError
puts "aws-sdk gem not found"
return #does not work
end
if library_found
namespace :db do
desc "import local postgres database to heroku. user and database name is hardcoded"
task :import_to_heroku => [:environment, "db:dump_for_heroku"] do
# code using aws-sdk gem
end
end
end
Run Code Online (Sandbox Code Playgroud)
LoadError希望程序在引发后继续执行。IE。优雅地处理LoadError并且不加载LoadError在同一文件中写入的代码。不能 raiseexit或abortonLoadError特别是后面的代码LoadError不应由 ruby 解释器执行(或加载)
最初问过如何在 ruby 中跳过 require? 但我没有正确地提出问题。希望措辞更好
我还没有检查源代码,但我想,当您在ruby my_file.rb控制台运行时,或者require/load从 Ruby 代码运行时,该文件在评估之前会被完全读入内存。恐怕没有跳过文件的一部分这样的事情。
我有一个关于捕捉/抛出的想法。
需要文件(例如 Rake 任务?) treq1.rb :
catch :aws_sdk do
require_relative 'original'
end
puts '... continued'
Run Code Online (Sandbox Code Playgroud)
您不想修改的原始文件,original.rb:
puts 'in original, not to be modified'
begin
require 'aws-sdk'
rescue LoadError
puts "aws-sdk gem not found"
throw :aws_sdk
end
puts ">>> to execute only if 'aws-sdk' is found"
# namespace :db do ... etc
#end
Run Code Online (Sandbox Code Playgroud)
执行 :
$ ruby -w treq1.rb
in original, not to be modified
aws-sdk gem not found
treq1.rb:2:in `require_relative': method `backtrace' called on unexpected T_NODE object (0x007fd32b88e900 flags=0x381c klass=0x0) (NotImplementedError)
from treq1.rb:2:in `block in <main>'
from treq1.rb:1:in `catch'
from treq1.rb:1:in `<main>'
Run Code Online (Sandbox Code Playgroud)
谷歌搜索错误:http://www.ruby-forum.com/topic/4406870
最近的帖子,没有答案。如果您想包装代码,它可以在单个文件中工作。
让我们尝试另一个解决方案。假设您可以更改 Rake 任务 treq2.rb :
begin
require_relative 'original'
rescue LocalJumpError
puts 'rescued LocalJumpError'
end
puts '... continued'
Run Code Online (Sandbox Code Playgroud)
在original.rb中,替换throw :aws_sdk为return:
$ ruby -w treq2.rb
in original, not to be modified
aws-sdk gem not found
rescued LocalJumpError
... continued
Run Code Online (Sandbox Code Playgroud)
这样就可以了。
华泰