我不明白,"dungeon.rb"如何运行正常,而"tarifs.rb"
则粉碎:undefined 方法 'full_description' for nil:NilClass(NoMethodError).
这两段代码是相似的。 有什么不同:类的名称,一些方法名称及其参数。
### 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 + "nn ** 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 代码必须允许在 tarifs.rb 中导航 - 就像 dungeon.rb 代码允许在房间中导航一样。同时,tarifs.rb 输出显示:
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'
您正在nil
上呼叫 mehtod full_description
.问题在于这些方法:
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
您根据find_tarif_in_tarifs(@user.choosed_tarif)
的结果调用full_description
,即在@tarifs[@user.choosed_tarif]
上。显然,没有在哈希@tarifs
为该用户注册关税。
您必须处理这种情况 - 通过检查返回值是否不是 nil, 定义show_current_description if find_tarif_in_tarifs(@user.choosed_tarif) 将"当前 tarif 是:"find_tarif_in_tarifs(@user.choosed_tarif).full_description 还 把"未找到关税" 结束
或通过从find_tarif_in_tarifs
返回默认值
def show_current_description
@tarifs.fetch(references, default_tariff) #(you need to define default_tariff method)
end