5


ライブラリ(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

アーリーリターンのようですが、関数ではなくファイルのロード用です。

私はrubygemを必要とするaws-sdkレーキタスクを持っているのでそれが必要ですが、私はそれを私のローカルマシンでのみ使用しています。見つからない場合aws-sdkは、後で同じファイルにコードをロードしても意味がありません。コードを小さなファイルに分割して、require呼び出しでワープできると思います

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

または条件付きの場合

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し、ロードしないでください。そして、特に後のコードは、rubyインタープリターによって実行(またはロード)されるべきではありませLoadErrorexitabortLoadErrorLoadError

もともとルビーでrequireをスキップする方法を尋ねていましたか? しかし、私はきちんと質問をしませんでした。これがより良い言葉であるといいのですが

4

2 に答える 2

3

ソースを確認していませんがruby my_file.rb、コンソールで実行する場合、またはrequire/loadRubyコードから実行する場合、ファイルは評価される前に完全にメモリに読み込まれると思います。ファイルの一部をスキップするようなことはないのではないかと思います。

キャッチ/スローのアイデアがありました。

必要なファイル(たとえば、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>'

エラーでグーグル:http
://www.ruby-forum.com/topic/4406870 最近の投稿、回答なし。コードをラップしたい場合は、単一のファイルで機能します。
別の解決策を試してみましょう。Rakeタスクを変更できると仮定すると、treq2.rb:

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

puts '... continued'

throw :aws_sdkoriginal.rbで、次のように置き換えreturnます。

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

このように動作します。
HTH

于 2013-01-25T21:00:42.630 に答える
1

「トップレベルリターン」機能が追加されました。

return「条件付きの場合」の例のように、トップレベルでキーワードを使用できるようになりました。ここでさらに議論します

于 2019-01-31T16:53:10.420 に答える