我可以有条件地跳过在同一个文件中加载“更多”ruby代码吗?

我可以有条件地跳过在同一个文件中加载“更多”ruby代码,
如果找不到库(通过require加载)?

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 

在上面的代码中,我可以要求Ruby在遇到rescue LoadError后不再加载文件。

就像早期返回一样,但是用于加载文件而不是用于函数。

需要它,因为我有一个需要aws-sdk rubygem的rake任务,但我只在我的本地机器上使用它。 如果找不到aws-sdk ,那么在我之后在同一个文件中加载代码是没有意义的。 我想我可以将代码拆分成较小的文件并在require调用中将其扭曲

 if Rails.env.development? require 'import_to_heroku' end 

但是不想扭曲或修改我现有的代码

此外,我可以将整个代码包装在条件中,但这是不优雅的。 开始救援区块也是一种明确的控制流程。 我不想以任何方式包装或触摸原始代码

也许是一个如api

 require_or_skip_further_loading 'aws-ruby` 

所以我希望我的代码在function上等同于

 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 

或者通过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 

LoadError之后,希望程序执行继续。 即。 优雅地处理LoadError并且不要在同一文件中加载在LoadError之后写入的代码。 无法在LoadError上引发exitabort特别是LoadError不应执行(或加载) LoadError之后的代码

原来问过如何跳过ruby中的要求? 但我没有正确地提出这个问题。 希望这措辞更好

我没有检查过源代码,但我想,当你在控制台上运行ruby my_file.rb ,或者从Ruby代码中require/load它时,文件在被评估之前会被完全读入内存。 我担心没有跳过文件的一部分。

我对catch / throw有一个想法。

需要文件(例​​如Rake任务?)treq1.rb:

 catch :aws_sdk do require_relative 'original' end puts '... continued' 

您不想修改的原始文件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 

执行:

 $ 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 
' from treq1.rb:1:in `catch' from treq1.rb:1:in `
'

谷歌搜索错误: http : //www.ruby-forum.com/topic/4406870
最近的post,没有答案。 如果要包装代码,它可以在单个文件中工作。
让我们尝试另一种解决方案。 假设您可以更改Rake任务,treq2.rb:

 begin require_relative 'original' rescue LocalJumpError puts 'rescued LocalJumpError' end puts '... continued' 

在original.rb中,通过return替换throw :aws_sdk

 $ ruby -w treq2.rb in original, not to be modified aws-sdk gem not found rescued LocalJumpError ... continued 

这种方式有效。
HTH