🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

456閲覧

Ruby []' for nil:NilClassの解決

Akihide

総合スコア8

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

1グッド

0クリップ

投稿2019/11/14 13:01

編集2019/11/14 13:21

前提・実現したいこと

プログラミングの勉強を始めて2ヶ月目です。
rubyでLivedoor の「お天気Webサービス」の API から情報を取得し、
ターミナルで表示するアプリを作っています。
Livedoorのデータで時間帯によっては最高気温または最低気温がnullの場合があります。undefined method `[]' for nil:NilClass (NoMethodError)

この場合に"データなし"等と表示したいのですが、どうしたら良いでしょうか。(データがnullでない場合は正常に作動します)
ruby -v 5.2.1
ご教示宜しくお願い致します。

if tomorrow_forecast["temperature"]["max"]["celsius"] = nil
条件
等googleで見つかったことは試しましたが、解決しなかったため具体的なコードを教えて頂きたいです。

該当のソースコード

require 'uri' require 'net/http' require 'json' require 'date' def tenki_tokyo tokyo = "http://weather.livedoor.com/forecast/webservice/json/v1?city=130010" info(tokyo) end def info(place) uri = URI.parse(place) res = Net::HTTP.get(uri) res = JSON.parse(res) location = res["location"]["city"] today = Date.today.day tommorow = Date.today.day + 1 forecasts = res["forecasts"] today_forecast = forecasts[0] today_telop = today_forecast["telop"] today_max = today_forecast["temperature"]["max"]["celsius"] today_min = today_forecast["temperature"]["min"]["celsius"] tomorrow_forecast = forecasts[1] tomorrow_telop = tomorrow_forecast["telop"] tomorrow_max = tomorrow_forecast["temperature"]["max"]["celsius"] tomorrow_min = tomorrow_forecast["temperature"]["min"]["celsius"] puts " #{location}の天気: 今日(#{today}日) :#{today_telop}、最高気温:#{today_max}、最低気温:#{today_min} 明日(#{tommorow}日) :#{tomorrow_telop}、最高気温:#{tomorrow_max}、最低気温:#{tomorrow_min}" end def end_program exit end def exception puts "入力された値は無効な値です" end while true do # メニューの表示 puts "天気を確認したい地名を選択して下さい。" puts "\n[1]東京\n[0]アプリを終了する" input = gets.to_i if input == 1 then tenki_tokyo elsif input == 0 then end_program else exception end end
DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

dig使うとよいと思います

ruby

1 today_max = today_forecast.dig(*%w[temperature max celsius]) || "データなし" 2 today_min = today_forecast.dig(*%w[temperature min celsius]) || "データなし"

投稿2019/11/14 15:44

編集2019/11/14 15:44
asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Akihide

2019/11/14 23:37

ありがとうございました。 上記コードで無事解決できました。
guest

0

次のコードを研究してみてください。

u.rb

ruby

1def foo(v) 2 return "データなし" if v == nil || v =="" 3 v.to_i 4end 5 6data = [10, nil, "10"] 7z = [10, nil, "10"].map {|x| foo(x)} 8 9pp data 10pp z

実行例
イメージ説明

投稿2019/11/14 14:52

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Akihide

2019/11/14 23:38

回答ありがとうございます。 研究致します。
guest

0

まえもってそいつがnilかどうかを判定すればいいのでは

投稿2019/11/14 13:18

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Akihide

2019/11/14 13:23

おっしゃる通りなのかと思いますが、試した限りうまくいかなかった為、お手数ですが具体的なコードを教えて頂けますでしょうか。
y_waiwai

2019/11/14 13:24

「ruby nil判定」でぐぐってみましょう
Akihide

2019/11/14 13:26 編集

.nil? ですよね。ググりまして、1時間以上あれこれいじりましたが解決しなかったのです。お助けください。
y_waiwai

2019/11/14 13:29

> if tomorrow_forecast["temperature"]["max"]["celsius"] = nil まずは、 tomorrow_forecast tomorrow_forecast["temperature"] tomorrow_forecast["temperature"]["max"] のどれがnilかを調べてみましょう
Akihide

2019/11/14 13:36 編集

Apiのデータを見るとtomorrow_forecast["temperature"]["max"]["celsius"] の["celsius"]がnullかと認識していましたが、違いますでしょうか。 よろしくお願い致します。
y_waiwai

2019/11/14 13:36

ちがいます。 きちんと確認しよう
Akihide

2019/11/14 13:39

初心者で全然わからないのです、何卒確認方法も合わせて教えて下さいませ。 プンプン丸です。
y_waiwai

2019/11/14 13:46

それらの変数をプリントアウトするなりしてナカミを確認してみては。 コードをデバッグできるような環境を整えよう。
Akihide

2019/11/14 14:29 編集

ご返信ありがとうございます。printしたところ、 tomorrow_forecast["temperature"]がnilではないかと考えました。 tomorrow_forecastのナカミは下記の通りでしたが、 tomorrow_forecast["temperature"]ではnilのようです。 ``` {"dateLabel"=>"今日", "telop"=>"晴れ", "date"=>"2019-11-14", "temperature"=>{"min"=>nil, "max"=>nil}, "image"=>{"width"=>50, "url"=>"http://weather.livedoor.com/img/icon/1.gif", "title"=>"晴れ", "height"=>31}} ``` そのため、下記のように(その他数パターン)試しましたが、やはりエラーでした。 ``` if today_forecast["temperature"].nil? today_max = "データなし" else today_max = today_forecast["temperature"]["max"]["celsius"] end ``` アドバイスお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問