Reputation: 35
I am using the "stock quote" gem (https://github.com/tyrauber/stock_quote) to retrieve stock prices based on user input tickers. While I have a ticker list that is up-to-date, there are some circumstances where the search yields no results. I have this in my code to get the quote:
@companyname = StockQuote::Stock.quote(@ticker).company
@exchange = StockQuote::Stock.quote(@ticker).exchange
@price = StockQuote::Stock.quote(@ticker).last
And it yields this when @ticker = "AKO-A"
undefined method `attributes' for nil:NilClass
file: stock.rb location: block in parse line: 90
Is there anyway to avoid this nomethoderror by making my code more robust (if error then "blank")? Sorry, I am relatively new to ruby and would appreciate any help to point me in the right direction.
Upvotes: 1
Views: 829
Reputation: 11
Here is an example on how use rescue to get around the nonexistent stock symbol problem
require 'stock_quote'
class StockClass
def self.symbol_check(symbol)
StockQuote::Stock.quote(symbol).symbol
end
def self.price_by_symbol(symbol)
StockQuote::Stock.quote(symbol).latest_price
end
def self.write_price_by_symbol(symbol, price)
filename = "#{symbol}.csv"
todays_date = Time.now.strftime('%Y-%m-%d')
File.open(filename, "a") do |file|
file << "#{todays_date}, #{price}\n"
end
end
end
def stock_price_selector(*symbol_array)
symbol_array.each do |stock_name|
begin
stock_check = StockClass.symbol_check(stock_name)
rescue NoMethodError
puts "#{stock_name} is a bogus ticker symbol"
else
stock_price = StockClass.price_by_symbol(stock_name)
stock_written = StockClass.write_price_by_symbol(stock_name, stock_price)
end
end
end
stock_price_selector('AAPL', 'APPL', 'MSFT', 'GOOG')
This will skip the bogus symbol 'APPL' and work for the legtimate ticker symbols.
Upvotes: 1
Reputation: 21
Yeah, the problem was definitely with the gem. It was assuming the symbol was accurate and wasn't properly parsing responses for bad symbols.
Sloppy. Rewrote the classes for cleaner code and greater stability. Added in a response_code instance method, which returns 200 or 404, depending upon the validity of the response. Also, a success? or failure? instance method. And, better spec coverage.
Version bumped, and pushed to rubygems.
Upvotes: 2
Reputation: 27207
This is a very common condition with Ruby code, and a common idiom to return nil
on a failed search.
However this specific gem is a little flaky when it fails to get a good search result. You can protect yourself against it failing by using a begin ... rescue
block.
begin
stock_quote = StockQuote::Stock.quote(@ticker)
rescue StandardError
stock_quote = nil
end
if stock_quote
@companyname = stock_quote.company
@exchange = stock_quote.exchange
@price = stock_quote.last
end
This might not be ideal program flow for you, so you may need to adapt this.
Note StandardError
is what gets rescued by default, I didn't need to write that. You could also put NoMethodError
in your situation, and usually you want to restrict rescuing exceptions to specific parts of code where you know how to recover from the error, and also only to the types of errors where you are confident that your handling code is doing the right thing.
Upvotes: 1