1

次のコードがあります。

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://i.dbastatic.dk/images/2/68/500656768_20012012182407_0401_2.jpg')
  return f
rescue => e
  raise CustomException.new(e.message)
end

今、私が次のことをすると:

begin
  file.body
rescue CustomException
  puts "rescued it!"
end

私は得る:

NoMethodError: nil:NilClass の未定義のメソッド「body」

開いている uri からの 404 エラー メッセージを含む CustomException の代わりに。奇妙なことに、代わりに次のようにすると:

begin
  f = file
  f.body
rescue CustomException
  puts "rescued it!"
end

その後、.body を実行しようとする前に、キャッチできる CustomException を取得します。わからない どうして?そして、ファイルメソッドを期待どおりに変更するにはどうすればよいですか?

4

3 に答える 3

2

問題を示すためのほんの少しの変更:

require 'open-uri'

def file
  f = Kernel.open('fill_in_some_url_that_returns_a_404')
  return f
rescue => e
  puts e.message
  1 ##<<---- inserted
end

file.body

いいえ、undefined method 'body' for 1:Fixnum

説明:メソッドはを実行しますputs e.messageが、結果を返しません(つまり、。を返しnilます)。

あなたと一緒に(結果とともに)file.body呼び出します。そして、この結果であなたはを呼び出します。しかし、これはには存在しません。したがって、エラーが発生しますfilenilbodynilundefined method 'body' for nil:NilClass

やってみたら

f = file
f.body

同じエラーが発生します。

確かに、両方の呼び出しで同じURLを使用しますか?URLを開くことができる場合は、有効なオブジェクトを再実行します。


実際、私はこれ以上のコードなしではあなたの問題を見ることができません。

コードをチェックして、次のことを確認できます。

変数とメソッドを定義すると、変数fileを取得します。以下の例を参照してください。おそらくこれが問題です。

file = nil
def file
  1
end

file.body   #undefined method `body' for nil:NilClass (NoMethodError)
file().body #undefined method `body' for 1:Fixnum (NoMethodError)

確実にメソッドを取得するには、を試すことができますfile()

于 2012-09-17T21:48:20.610 に答える
1

あなたは自分自身を混乱させたと思います。問題を説明しているように見える唯一のコードは次のとおりです。

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException
  puts "rescued it!"
end

さて、そのコードを実行したところ、「救出」されました。それは人が期待するものではありませんか?あなたが示したコードでは、私は決して得られNoMethodError: undefined method body for nil:NilClassませんし、あなたもそうするとは思いません。

それで、本当に問題は何ですか?404 メッセージが stdout に渡されていないということですか? それがあなたが望むものなら、あなたは書くべきでした:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException => e
  puts "rescued it!", e.message
end
于 2012-09-17T23:12:19.853 に答える
0

これはおそらくあなたが望むものです:

require 'open-uri'

def file(url)
 begin
  Kernel.open(url)
 rescue => e
  puts e.message
 end
end

最初に有効な URL を試してみましょう。

f = file('http://www.google.com/')
puts f.read if !f.nil?

それでは、404 を返す URL で試してみましょう。

f = file('http://www.google.com/blahblah')
puts f.read if !f.nil?

編集: 存在しない URL で呼び出されると、コードは 2 つのエラーを発生させます。「file」メソッドは OpenURI::HTTPError を発生させますが、「body」メソッドは nil で呼び出されるため NoMethodError を発生させます。最初の使用例では、これら 2 つのエラーを 1 つのステートメントで発生させます。2 番目の使用例では、エラーは連続しています。それでも、同じ結果が得られるはずであり、私にとってはそうです。

于 2012-09-17T22:17:52.243 に答える