我可以有条件地跳过在同一个文件中加载“更多”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
上引发exit
或abort
特别是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