I don't get it, how "dungeon.rb" runs ok, while "tarifs.rb" crushes with:
undefined method 'full_description' for nil:NilClass(NoMethodError).
Both piece of code are similar. what is different: Names of classes, some methods names and their arguments.
### OK piece -> dungeon.rb code
class Dungeon
attr_accessor :player
def initialize(player)
@player = player
@rooms = {}
end
def add_room(reference, name, description, connections)
@rooms[reference] = Room.new(reference, name, description, connections)
end
def start(location)
@player.location = location
show_current_description
end
def show_current_description
puts "Location: " + find_room_in_dungeon(@player.location).full_description
end
def find_room_in_dungeon(reference)
@rooms[reference]
end
def find_room_in_direction(direction)
find_room_in_dungeon(@player.location).connections[direction]
end
def go(direction)
puts "\nYou go: " + direction.to_s
@player.location = find_room_in_direction(direction)
show_current_description
puts "Where you want to go now? "
end
end
class Player
attr_accessor :name, :location
def initialize(name)
@name = name
end
end
class Room
attr_accessor :reference, :name, :description, :connections
def initialize(reference, name, description, connections)
@reference = reference
@name = name
@description = description
@connections = connections
end
def full_description
@name + "\n\n ** You are in " + @description
end
end
#######---------------- Creating Player and Dungeon objects ------------------
puts "Enter your name"
username = gets.chomp
player = Player.new(username)
my_dungeon = Dungeon.new(player)
#######---------------- Add rooms to the dungeon ----------------------
my_dungeon.add_room(:largecave,
"Large Cave",
"a large cavernous cave **",
{:west => :smallcave,
:south => :grotto,
:east => :largecave })
my_dungeon.add_room(:smallcave,
"Small Cave",
"a small, claustrophobic cave **",
{:west => :smallcave,
:south => :grotto,
:east => :largecave })
my_dungeon.add_room(:grotto,
"Wet Grotto",
"a medium range grotto with water pool in center **",
{:west => :smallcave,
:south => :grotto,
:east => :largecave })
puts "Your name is: #{player.name}"
#######------------ Start the dungeon by placing the player in the large cave ------------------------
my_dungeon.start(:largecave)
#######------------- Player navigation ---------------------
ok_input = [:west, :east, :south, :exit]
loop do
puts "Choose direction please: "
input = gets.chomp.to_sym
if ok_input.include?(input)
my_dungeon.go(input)
elsif ok_input.include?(input) == false
puts "Wrong input!!! Allowed input: 'west', 'east', 'south' or 'exit' "
end
break if input == :exit
end
#### NOT OK piece -> tarifs.rb code
class Invest
attr_accessor :user
def initialize(user)
@user = user
@tarifs = {}
end
def add_tarif(reference, tname, description, connections, procent, days)
@tarifs[reference] = Tarif.new(reference, tname, description, connections, procent, days)
end
def start(choosed_tarif)
@user.choosed_tarif = choosed_tarif
show_current_description
end
def show_current_description
puts " Current tarif is: " + find_tarif_in_tarifs(@user.choosed_tarif).full_description
end
def find_tarif_in_tarifs(reference)
@tarifs[reference]
end
def find_tarif_in_direction(direction)
find_tarif_in_tarifs(@user.choosed_tarif).connections[direction]
end
def go(direction)
puts "\nYou choosed: " + direction.to_s
@user.choosed_tarif = find_tarif_in_direction(direction)
show_current_description
end
end
class User
attr_accessor :uname, :choosed_tarif
def initialize(uname)
@uname = uname
end
end
class Tarif
attr_accessor :reference, :tname, :description, :connections, :procent, :days
def initialize(reference, tname, description, connections, procent, days)
@reference = reference
@tname = tname
@description = description
@connections = connections
@procent = procent
@days = days
end
def full_description
@tname + "\n " + @description
end
end
#######-------- Creating User and Invest objects ----------
puts "Enter your name"
uname = gets.chomp
user = User.new(uname)
my_tarif = Invest.new(user)
#######-------- Adding tariffs to the Invest --------------
my_tarif.add_tarif(:start,
"Start",
"Start tarif 2% daily for 3 days in total",
{:first => :start,
:second => :business,
:third => :profi },
2,
3)
my_tarif.add_tarif(:business,
"Business",
"Business tarif 3% daily for 5 days in total",
{:first => :start,
:second => :business,
:third => :profi },
3,
5)
my_tarif.add_tarif(:profi,
"Profi",
"Profi tarif 4% daily for 10 days in total",
{:first => :start,
:second => :business,
:third => :profi },
4,
10)
#######-------- Autostarts with first tarif --------------
my_tarif.start(:business)
#######-------- Tarif navigation --------------
ok_input = [:start, :business, :profi, :exit]
puts "Choose your tarif: "
input = gets.chomp.to_sym
if input == :start
my_tarif.go(input)
elsif input == :business
my_tarif.go(input)
elsif input == :profi
my_tarif.go(input)
else puts "Please input 'start', 'business' or 'profi' !!!"
end
tarifs.rb code must allow to navigate in tarifs.rb - just like dungeon.rb code allows to navigate in rooms. Meanwhile, tarifs.rb output shows folowing:
tarifs.rb:22:in show_current_description': undefined methodfull_description' for nil:NilClass (NoMethodError) from tarifs.rb:36:in go' from tarifs.rb:111:in'
You are calling a mehtod full_description
on a nil
. The problem lays in those methods:
def show_current_description
puts " Current tarif is: " + find_tarif_in_tarifs(@user.choosed_tarif).full_description
end
def find_tarif_in_tarifs(reference)
@tarifs[reference]
end
Youl call full_description
on a result of find_tarif_in_tarifs(@user.choosed_tarif)
. ie on @tarifs[@user.choosed_tarif]
. Apparently there is not tariff registered for this user in @tarifs
hash.
You have to handle this case - either by checking if returned value is not nil, def show_current_description if find_tarif_in_tarifs(@user.choosed_tarif) puts " Current tarif is: " + find_tarif_in_tarifs(@user.choosed_tarif).full_description else puts "No tariff found" end
or by returning a default value from find_tarif_in_tarifs
def show_current_description
@tarifs.fetch(references, default_tariff) #(you need to define default_tariff method)
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.