我可以有条件地跳过加载吗;“进一步”;同一文件中的ruby代码?
我是否可以有条件地跳过在同一文件中加载“进一步”ruby代码,我可以有条件地跳过加载吗;“进一步”;同一文件中的ruby代码?,ruby,rubygems,require,Ruby,Rubygems,Require,我是否可以有条件地跳过在同一文件中加载“进一步”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 "==
如果找不到库(通过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在以后不要再加载文件吗
击中救援装载错误
类似于提前返回,但用于加载文件而不是函数。
需要它,因为我有一个rake任务,它需要awsdk
rubygem,但我只使用它
在我的本地机器上。如果未找到aws sdk
,则以后在同一文件中加载代码是没有意义的。我想我可以将代码拆分成更小的文件,并将其扭曲
紧急电话
if Rails.env.development?
require 'import_to_heroku'
end
但不想扭曲或修改我现有的代码
此外,我可以将整个代码包装在一个条件中,但这是不雅观的。
begin rescue块也是显式控制流的一种形式。
我不想以任何方式包装或触摸原始代码
可能是一个api,比如
require_or_skip_further_loading 'aws-ruby`
所以我希望我的代码在功能上与
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
之后的代码不应由ruby解释器执行(或加载)
原来问过
但我没有正确地提出这个问题。希望这是更好的措辞我还没有检查源代码,但我想,当您在控制台上运行
ruby my_file.rb
或require/load
从ruby代码中加载它时,该文件在计算之前会被完全读取到内存中。恐怕没有跳过文件的一部分这样的事情
我有个接球/掷球的主意
需要文件(例如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 <main>'
from treq1.rb:1:in `catch'
from treq1.rb:1:in `<main>'
在original.rb中,将throw:aws_sdk
替换为return
:
$ ruby -w treq2.rb
in original, not to be modified
aws-sdk gem not found
rescued LocalJumpError
... continued
这样就行了。HTH是“顶级返回”功能
现在可以在顶层使用
return
关键字,如“通过一个if条件”示例 不需要“跳过”文件的其余部分,因为它已经“加载”了。如果出现rescue LoadError
,代码将终止(使用return
或最好是exit
),Ruby将不处理文件的其余部分。@BernardK谢谢。编辑了这个问题。希望它等同于将其包装在问题中提出的begin rescue或if块中。相关部分如下所示。希望在引发LoadError
后继续执行程序。即:优雅地处理LoadError
,不要将LoadError
之后编写的代码加载到同一文件中。无法在LoadError
上引发exit
或abort
,尤其是LoadError
之后的代码不应由ruby解释器执行(或加载)。此文件是如何加载的?我不知道。它需要你的文件吗?我想Ruby 2正在考虑这个问题。我不知道是否有任何实现已经进入Ruby 2预览版。的可能副本不理解第二个示例,即使用LocalJumpError
。在第一个示例中,我没有得到任何错误。我使用的是ruby 1.9.3p327您使用的是两个单独的文件吗?错误只发生在两个文件中。是的。实际代码(从示例中复制)和输出位于。我使用的是MRI ruby 1.9.3p327(2012-11-10版本37606)[x86_64-darwin10.8.0]ruby安装没有任何自定义补丁我已经安装了ruby-1.9.3-p362。现在,将catch/throw分发到两个文件中的版本以及return/rescue版本都可以正常工作。你现在快乐吗?这就是你想要的吗?@deepak回答你的第一个评论:如果你运行ruby original.rb
,返回而不是throw
,“rescue in”中的错误:意外返回(LocalJumpError)
,但是如果需要从另一个文件运行original.rb,我们可以捕获错误,解救它并继续。
$ ruby -w treq2.rb
in original, not to be modified
aws-sdk gem not found
rescued LocalJumpError
... continued