Ruby:为什么第二段代码与第一段代码相似-gives';未定义的方法';错误?

Ruby:为什么第二段代码与第一段代码相似-gives';未定义的方法';错误?,ruby,null,Ruby,Null,我不明白,“dungeon.rb”如何运行正常,而“tarifs.rb”如何运行: nil:NilClass(NoMethodError)的未定义方法“完整描述” 这两段代码是相似的。不同之处:类的名称、某些方法的名称及其参数 ### OK piece -> dungeon.rb code class Dungeon attr_accessor :player def initialize(player) @player = p

我不明白,“dungeon.rb”如何运行正常,而“tarifs.rb”如何运行:

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 + "\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:来自tarifs.rb:36:in go'from tarifs.rb:111:in'


您正在调用
nil
上的方法
full\u 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
您可以调用
full\u description
,查询
find\u tarif\u in\u tarifs(@user.choosed\u tarif)
。i、 e.在
@tarifs[@user.choosed\u tarif]
上。显然,
@tarifs
散列中没有为该用户注册关税

您必须处理这种情况-通过检查返回值是否不是nil, def显示_当前_说明 if find_tarif_in_tarifs(@user.choosed_tarif) 将“当前tarif is:”+在tarifs(@user.choosed\u tarif)中查找tarif。完整描述 其他的 放入“未找到关税” 结束

或者从
find\u tarif\u in\u tarifs

   def show_current_description
     @tarifs.fetch(references, default_tariff) #(you need to define default_tariff method)
   end