Can I conditionally skip loading "further" ruby code in the same file,
if a library (loaded via require) is not found ?
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
In the above code, can I ask Ruby not to load the file further after
hitting a rescue LoadError
.
Like an early return but for loading a file and not for a function.
Need it because i have i have a rake task which needs aws-sdk
rubygem but i use it only
on my local machine. If aws-sdk
is not found it does not make sense for me to load code afterwards in the same file. I guess i can split the code into smaller files and warp it in
a require call
if Rails.env.development?
require 'import_to_heroku'
end
But do not want to warp or modify my existing code
Also, i can wrap the whole code in an conditional but that is inelegant. A begin-rescue block is also a form of explicit control flow. I do not want to wrap or touch the original code is any manner
Maybe an api such as
require_or_skip_further_loading 'aws-ruby`
So i want my code to be functionally equivalent to
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
Or via an if conditional
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
Want program execution to continue after LoadError
is raised. ie. gracefully handle LoadError
and do not load code written after LoadError
in the same file. cannot raise exit
or abort
on LoadError
And particularly the code after LoadError
should not be executed (or loaded) by the ruby interpreter
Had originally asked How to skip require in ruby? but i did not ask the question properly. hope this is better worded
I haven't checked the source, but I suppose that, when you run ruby my_file.rb
at the console, or require/load
it from Ruby code, the file is read entirely into memory before being evaluated. I'm afraid there is no such thing as skipping a part of a file.
I had an idea with catch/throw.
requiring file (for example a Rake task ?) treq1.rb :
catch :aws_sdk do
require_relative 'original'
end
puts '... continued'
The original file that you don't want to modify, 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
Execution :
$ 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>'
Googling with the error : http://www.ruby-forum.com/topic/4406870
Recent post, no answer. It works in a single file, if you want to wrap your code.
Let's try another solution. Supposing that you can change the Rake task, treq2.rb :
begin
require_relative 'original'
rescue LocalJumpError
puts 'rescued LocalJumpError'
end
puts '... continued'
In original.rb, replace throw :aws_sdk
by return
:
$ ruby -w treq2.rb
in original, not to be modified
aws-sdk gem not found
rescued LocalJumpError
... continued
This way it works.
HTH
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With