Accessing instances of a clss using a variable based on user input


#1

I am trying to extend the program to include to option to create multiple lists. So far, most of it is working, however I am having an issue with calling methods on a list name inputted by the user. Here is my code:

#-------------------Menu----------------------
module Menu
	def menu 
		"Welcome to the ToDoList Program:
		Menu: Type a number to select a choice

		1) Create a new to do list
		2) Add a new task to an existing to do list
		3) Display all to do lists
		4) Show tasks on a to do list
		5) Delete a current list
		6) Quit program "
	end

	def show_menu
		menu
	end
end

module Promptable
	def prompt(message = "What would you like to do?", symbol = ":> " )
		print message
		print symbol
		gets.chomp
	end
end

#----------------Classes--------------------
class Program
	def initialize
		$all_lists =[]
	end


	attr_reader :all_lists

	def display_lists
		$all_lists
	end
end


class List < Program
	def initialize(name)
		@name = name
		$all_lists << @name
		@all_tasks = []
		puts "You have created a new list, #{@name}."
	end

	attr_reader :all_tasks

	def add(task)
		@all_tasks << task
		puts "You have added a task to your list."
	end

	def show
		@all_tasks
	end
end




class Task
	def initialize(description)
		@description = description
	end

	attr_reader :description
end


if 'todolist.rb' == $PROGRAM_NAME
	include Menu
	include Promptable
	my_program = Program.new


	until ['6'].include?(user_input = prompt(show_menu))
			case user_input 
				when '1'
					puts "Enter the name of your new list:"
					in_name  = gets.chomp
					in_name = List.new(in_name)

				when '2'
					puts "Enter list you would like to add a task to:"
					in_name = gets.chomp
					if $all_lists.include?(in_name)
						continue = "YES"
						while continue == "YES" do
							in_name.add(Task.new(prompt('What is the task you would like to accomplish?')))
							continue = prompt("Would you like to add another task? YES or NO")
							continue.upcase!
						end
					else puts "Error: Unknown list entered. Please try again."
					end

				when '3'
					puts my_program.display_lists

				when '4'
					puts "Enter list you would like to view: "
					in_name = gets.chomp
					if $all_lists.include?(in_name)
						puts in_name.show
					else puts "Error: Unknown list entered. Please try again."
					end
	
				when '5'
					puts "Enter name of list you would like to delete: "
					in_name = gets.chomp
					if $all_lists.include?(in_name)
						in_name.delete
					else puts "Error: Unknown list entered. Please try again."
					end

				else puts "Error: Invalid option. Please enter a valid option."
			end
			prompt('Press any key to return to menu', '')
	end

	puts "Thank you for using the To Do List Program! Goodbye."
end

I have an idea of what my issue is: the list name the user inputs is stored as a string. This is okay when checked against the array $all_lists (where the names of lists are stored so the program can check if they exist). However, the issue is that that instance of the class that is needed to call a method is not a string. I tried changing the in_name (inputted name) to a symbol, but it returned the error message:
todolist.rb:94:in': undefined method add' for :"my list":Symbol (NoMethodError)

This tells me that when it is turning in_name to a sym, it is keeping it wrapped in quotes, like a string (and therefore the program isn't recognizing it as an instance of the List class.

Basically, I know the issue but I have no idea how to fix it!

Any help would be much appreciated!


#2

A name isn't a list in any way, that doesn't make sense.
Look for a list with that name instead? (A hash is particularly well suited for that)


#3

I guess what I was asking wasn't clear (or might not know how to communicate what I'm asking so it makes sense)... The name isn't a list...its calling the name of a list (that was created as an instance of the List class). Before the user can add a task to the list, they have to create the list (option 1 in the menu). Then the name of that list is used to call methods defined in the list class (In all the examples, it would be something like my_list.add(task) ).

My issue is that, rather than the name of the list being defined in the program, the user is inputting the name, and can create multiple lists. So I'm trying to figure out how to call methods on those lists the user is creating.


#4

A hash allows you to map keys (names) to values (lists)
Once you've obtained the right list you can then call methods on it