ruby - Ruby:为什么第二段代码与第一段代码相似 - 给出“未定义方法”错误?
问题描述
我不明白,“dungeon.rb”如何运行正常,而“tarifs.rb”则与:
nil:NilClass(NoMethodError) 的未定义方法“full_description”。
两段代码相似。有什么不同:类的名称、一些方法名称及其参数。
### 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 代码必须允许在 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'
解决方案
你正在调用一个full_description
方法nil
。问题在于这些方法:
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
你会调用full_description
. find_tarif_in_tarifs(@user.choosed_tarif)
即在@tarifs[@user.choosed_tarif]
。@tarifs
显然,在哈希中没有为该用户注册关税。
您必须处理这种情况 - 要么通过检查返回值是否不为零,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 "未找到关税“ 结尾
或者通过返回一个默认值find_tarif_in_tarifs
def show_current_description
@tarifs.fetch(references, default_tariff) #(you need to define default_tariff method)
end
推荐阅读
- c++ - 如何将缓冲区值设置为零?
- python - pythonic 方法来识别 url 中的名称并将其与现有的一组名称匹配
- javascript - 客户端 javascript 的摘录在 Wordpress 页面的正文中显示为文本
- psycopg2 - 在ubuntu18上安装odoo12企业版时出现psycopg2包错误
- html - 奥丁项目——谷歌主页项目
- linux - 使用 Canon ImageClass D1320 打印机设置 CUPS,CUPS 无法识别?
- css - 如何正确在图像上使用绝对和相对定位?
- java - infixToPostfix 算法但没有操作优先级
- java - 导航抽屉活动未加载所有片段
- powershell - 获取电子邮件组成员的 PowerShell 命令 - Get-ADGroupMember 不起作用