Debugging simple Ruby class method? - ruby

class DobbsyKretts
def initialize
#Receive idea
puts "Enter an idea, a secret or anything else you want to secretize; hit enter to stop typing and save the file"
(#idea = gets).reverse.upcase
#Filename and saving - to encrypt the file
puts "Enter the file name you'd like to have this saved as; Type PLAN at the beginning for plans and REM for reminders"
(#file_name = gets.chomp.upcase)
File::open("DobbsyKrett-"+ #file_name + ".txt", "w") do |f|
f << #idea
end
end
def unzip
puts "Do you want to withdraw PLAN or REM"
response = gets.chomp.upcase!
puts "Invalid" if !["PLAN","REM"].include?(response)
file_contents = nil
Dir['DobbsyKrett-'+response+"*.txt"].each do |file_nom|
file_contents = File.read(file_nom)
end
puts file_contents
end
end
somethingsomething1 = DobbsyKretts.new
somethingsomething1.unzip
def unzip
puts "Do you want to withdraw PLAN or REM"
#response = gets.strip
if #response.downcase != "plan" and #response.downcase != "rem"
puts "Invalid" end
Dir["DobbsyKrett-"+#response+".txt"].each do |file_nom|
#value = file.read(file_nom)
end
puts #value
end
end

The function gets will return a string with the line-ending character at the end which is not what you expected. To remove it, use the chomp function:
#response = gets.chomp
It is okay for a method (e.g. unzip) to create new instance variables (e.g. #valueholder). In general it's always better for your variables to have the smallest possible scope, so unless you need to read valueholder later, you should just use a local variable (remove the # from the name):
Dir["DobbsyKrett-"+#response+".txt"].each do |file_nom|
valueholder = File.read(file_nom)
end
puts valueholder
Also, valueholder is a terrible name for a variable but if you made it a local variable that could be excused.
Also, your block startings/endings are mismatched. Here's a fixed version of your function that shouldn't result in syntax errors:
def unzip
puts "Do you want to withdraw PLAN or REM"
response = gets.chomp.downcase
if !["plan","rem"].include? response
puts "Invalid"
else
Dir["DobbsyKrett-#{response}.txt"].each do |file_nom|
valueholder = file.read(file_nom)
end
puts valueholder
end
end
Edit: You should capitalize File to correctly call File.read.

Related

Undefined method .split for Nil class Ruby

Undefined method for nil:Nilclass
In a class, a method counts the number of words in a paragraph.An error occurs when a method is called(1). I can’t understand how to pass the argument methods using send.
If I remove the class and put the def calc_1(paragraph) method into the loop, then everything works, I start calling the select method. It turns out he does not see my books variable with text, when there is a class.
#books = "You can use this knowledge to create small tools that might help."
class Filecalculation
def select
loop do
puts "# Will we search : сounting words in text File(1)".cyan
print "\n>>>>>> "
input = gets.chomp
search_method = "calc_#{input}".to_sym
if (respond_to?(search_method))
contents = send(search_method, #books)
end
end
end
def calc_1 paragraph
word_count = paragraph.split.length
puts "#{word_count} words"
end
end
Filecalculation.new.select
If replaced by search_method = "calc_#{input}".to_sym also works.
Helped add def initialize #books end.
Instead of contents = send (search_method, #books) you can use send (search_method, #books).
require "colorize"
class Filecalculation
def initialize
#books = "You can use this knowledge to create small tools that might help you."
end
def calc_1 paragraph
word_count = paragraph.strip.squeeze(' ').count(' ') + 1
puts "#{word_count} words"
end
def select
loop do
puts "# Will we search : Calculation_lines paragraph(1)".cyan
print "\n>>>>>> ".yellow
input = gets.chomp
search_method = "calc_#{input}" #.to_sym
if (respond_to?(search_method))
contents = send(search_method, #books)
else
puts "exit "
exit
end
end
end
end
Filecalculation.new.select

Why doesn't my hash work in Ruby?

I have this phonebook program that looks up all the contacts, deletes a contact, and adds a contact. I created a hash global variable called contactList. However, the program fails to recognize this. What did I do wrong?
class PhoneBook
contactList = hash.new
def Add(newContact = {})
flag = false
if newContact.length < 1
return flag
else
flag = true
newContact.collect do |name, number|
contactList[name] = number
end
return flag
end
end
def delete (targetName)
if !contactList.has_key?(targetName)
return false
else
contactList.delete(targetName)
return true
end
end
def displayContact (targetName)
number = -1
if contactList.has_key?(targetName)
number = contactList(targetName)
puts "Contact name : #{targetName}, Contact Number, #{number}"
else
puts "#{targetName} doesn't exist in the phonebook"
end
end
def displayAllContacts
if !contactList.empty?
contactList.each {|name, number| puts "Contact name: #{name}, contact number #{number}" }
else
puts "You don't have any contact details your phonebook"
end
end
end
Because you have defined class local variable contactList, whereas you wanted to have an instance variable.
Remove this line
contactList = hash.new
and add the following method:
def contactList
#contactList ||= {}
end
P.S. there is no such thing as hash.new, you most likely meant Hash.new.
P.P.S. By Ruby naming conventions your variables/methods names should be snake-cased, not camel cased.
So it should be contact_list.

How do I write an rspec 3.1 test for this

How do I write a rspec test for the following.
the value that gets passed in is this...
90A14F 1.4
def classname
def init
#input_colors = Array.new
end
def speak
puts "enter your line of color values"
result = STDIN.gets.chomp
new_result = result.gsub!(/([\s])+/,':')
#input_colors << new_result
end
end
How do I write an rspec 3.1 test for this speak method that test if gets.chomp is...90A14F 1.4
They will get an instance var #input_colors == ["90A14F:1.4"]
There are some issues in your example. I would change and fix it to something like this:
class ColorReader # with `class` and an upcase class name
def initialize # not `init`
#colors = [] # the use of `Array.new` is uncommon
end
def read
puts "enter your line of color values"
result = STDIN.gets.chomp
new_result = result.gsub!(/([\s])+/,':')
#colors << new_result
end
end
Then a test could look like this:
describe ColorReader do
describe '#read' do
let(:input) { "90A14F 1.4\n" }
subject(:color_reader) { ColorReader.new }
before do
allow(color_reader).to receive(:puts).and_return(nil)
allow(STDIN).to receive(:gets).and_return(input)
end
it 'writes to the console' do
color_reader.read
expect(color_reader).to have_received(:puts).
with("enter your line of color values").once
end
it 'reads from STDIN' do
color_reader.read
expect(STDIN).to have_received(:gets).once
end
it 'returns the sanitized input' do
expect(color_reader.read).to eq(['90A14F:1.4'])
end
end
end
Btw. I would prefer to explicitly test the new value of the #colors array (perhaps with attr_reader :colors) and not the implizit return value of the read method. If you have a reader for the #colors then the last spec can be changed to:
it 'adds the sanitized input to `colors`' do
expect {
color_reader.read
}.to change { color_reader.colors }.from([]).to(['90A14F:1.4'])
end

Undefined local variable or method 'user_response'

I've read my code up and down for about 30 mins now. I can't for the life of me see where user_response is undefined. I'm very new to coding so I don't know how much of the code would be appropriate to paste in here. I figure that launch and get_action are essential but the rest couldn't hurt?
error => rb:32:in `launch!': undefined local variable or method `user_response' for
<Guide:0x007fb019984718> (NameError)
class Guide
class Config
##actions = ['list', 'find', 'add', 'quit']
def self.actions
##actions
end
end
def initialize(path=nil)
# locate the restaurant text file at path
Restaurant.filepath = path
if Restaurant.file_usable?
puts "Found restaurant file."
# or IF a new text file can't be created, create a new file
elsif Restaurant.create_file
puts "Created restaurant file."
# exit if create fails
else
puts "Exiting"
exit!
end
end
def launch! #! means that it is a strong powerful method!
introduction
# action loop
result = nil
until result == :quit
action = get_action
result = do_action(user_response)
end
conclusion
end
def get_action
action = nil
# Keep asking for user input until we get a valid action
until Guide::Config.actions.include?(action)
puts "Actions: " + Guide::Config.actions.join(", ") if action
print "> "
user_response = gets.chomp
action = user_response.downcase.strip
end
return action
end
def do_action(action)
case action
when 'list'
puts "Listing..."
when 'find'
puts "Finding..."
when 'add'
puts "Adding..."
when 'quit'
return :quit
else puts " I don't understand that command."
end
end
def introduction
puts "<<< Welcome to the Food Finder >>>"
puts "This is an interactive guide to help you find the food you crave."
end
def conclusion
puts "<<< Goodbye and Bon Appetit! >>>>"
end
end
I think you want to do this :
def launch! #! means that it is a strong powerful method!
introduction
# action loop
result = nil
until result == :quit
result = do_action(get_action)
end
conclusion
end
The only time you define a variable called user_response is in your get_action method.
The way you define it there makes it a local variable and it will not be accessible from anywhere but inside the get_action method.

Why is my class variable still nil after I assign it? (Ruby)

According to my test, client_1 should be a client class which I have used to see if I can output and put it. I need to use #output variable in my client class is STILL NIL, but I assign it with the capture_output method in my client class.
#war_server.client_keys(0).puts("Hello Frodo") #works
temp_holder = client_1.capture_output #store output from server to temp holder
puts "Here is the captured input from client_1! : #{temp_holder}"#works
puts #client_1.output #DOES NOT WORK. But it should because I assin it in my class and use a reader definition
Here's the code for my classes and test. Thanks!
require 'minitest/autorun'
require 'socket'
require_relative 'WarGame_Class.rb'
require_relative 'ModifiedPlayer_Class.rb'
require_relative 'DeckClass.rb'
class WarServer
def initialize(host, port)
#socket_server = TCPServer.new(host, port)
#players = [Player.new, Player.new]
#deck = CardDeck.new
#deck.deal_cards(#players[0].cards, #players[1].cards)
game = WarGame.new
#clients = {} # keys are sockets, values are players
end
def client_keys(key)
#clients.keys[key] # this should work
end
def input #input reader function
#input
end
def close
#socket_server.close
end
def capture_input ##input client to get what they wrote
#input = #clients.keys[0].read_nonblock(1000) # arbitrary max number of bytes
end
def accept_client
#Hash here to link client to player? (or game?)
client = #socket_server.accept
#clients[client] = #players[#clients.size]
# puts "clients key 0: #{#clients.keys[0]}"
puts
# puts "clients values: #{#clients.values}"
if #clients.size == 2
start_game#####################!!!! Starts game if two clients can put client messages in start game
end
end
def start_game ##############!!!
#clients.keys[0].puts "Welcome to War. Please press enter to play your card"
#clients.keys[1].puts "Welcome to War. Please press enter to play your card"
end
end
class MockWarClient
def initialize
#socket = TCPSocket.new('localhost', 2012)
end
def output
#output
end
def input
#input
end
def capture_output #need to add (socket)? How else read from specific socket?
#output = #socket.read_nonblock(1000) # arbitrary max number of bytes
rescue
#output = "capture_output error."
end
def write_input
#input = #war_server.client_keys.write_nonblock(1000)
end
end
class WarServerTest < MiniTest::Unit::TestCase
def setup #This would be like our INITIALIZE Function
#anything is available through out all tests (i.e., instance vars)
#war_server = WarServer.new('localhost', 2012)
end
def teardown
#war_server.close
end
def test_server_capture_output_from_client
client_1 = MockWarClient.new
#war_server.accept_client
client_2 = MockWarClient.new
#war_server.accept_client
#can output #war_server.client_keys, though, if I take out the argument to pass in.
#puts "Test_Server_output #client keys #{#war_server.client_keys(player)}" #cient_1?
puts "Test_Server_output #client keys 0 #{#war_server.client_keys(0)}"
puts "Test_Server_output #client keys 1 #{#war_server.client_keys(1)}"
#war_server.client_keys(0).puts("Hello Frodo")
temp_holder = client_1.capture_output
puts "Here is the captured input from client_1! : #{temp_holder}"
#puts #war_server.input
puts #client_1.output
end
end
client_1 is a local variable, distinct from #client_1. I don't see anywhere in this code where you assign #client_1. Unless there is some code you're not sharing which does this, then #client_1 will evaluate to nil.
#client_1 is an instance variable, which is a variable on the instance of a class and exists for the duration that the object is in existence. In order to assign a value to an instance variable, you must denote it by preappending the variable name with #.
In contrast, client_1 is a local variable, which exists only within a single method or block. In your snippet, you have assigned a value to the client_1 local variable, but not to the#client_1 instance variable, which is nil until assigned.

Resources