2013-04-04 2 views
0

В настоящее время, начиная с главы 12 главы Ruby, он создает ботовую беседу. При запуске файла basic_client.rb загружается бот. Когда вводится «я ненавижу телевидение», бот должен распознавать шаблон со словом «ненависть» и возвращать ответ на основе шаблона.неинициализированная константа Bot :: Wordplay (NameError) from Beginning Ruby tutorial

Вместо этого он возвращает несколько ошибок имени из бот-файла. Все они привязаны к файлу wordplay.rb, однако я не уверен, что вызывает его. Любая помощь будет оценена по достоинству.

/bot.rb:73:in `block (2 levels) in possible_responses': uninitialized constant Bot::Wordplay (NameError) 
/bot.rb:69:in `collect' 
/bot.rb:69:in `block in possible_responses' 
/bot.rb:59:in `each' 
/bot.rb:59:in `possible_responses' 
/bot.rb:27:in `response_to' 
from basic_client.rb:8:in `<main>' 

Файл бежится: basic_client.rb

`require './bot' 

bot = Bot.new(:name => 'Fred', :data_file => 'fred.bot') 

puts bot.greeting 

while input = gets and input.chomp != 'end' 
puts '>> ' + bot.response_to(input) 
end 

puts bot.farewell` 

Необходимое bot.rb:

require 'yaml' 
require './wordplay' 

class Bot 
attr_reader :name 

def initialize(options) 
    @name = options[:name] || "Unnamed Bot" 
    begin 
     @data = YAML.load(File.read(options[:data_file])) 
    rescue 
     raise "Can't load bot data" 
    end 
end 

def greeting 
    random_response :greeting 
end 

def farewell 
    random_response :farewell 
end 

def response_to(input) 
    prepared_input = preprocess(input.downcase) 
    sentence = best_sentence(prepared_input) 
    responses = possible_responses(sentence) 
    responses[rand(responses.length)] 
end 

private 

def random_response(key) 
    random_index = rand(@data[:responses][key].length) 
    @data[:responses][key][random_index].gsub(/\[name\]/, @name) 
end 

def preprocess(input) 
    perform_substitutions(input) 
end 

def perform_substitutions(input) 
    @data[:presubs].each { |s| input.gsub!(s[0], s[1]) } 
    input 
end 

def best_sentence(input) 
    hot_words = @data[:responses].keys.select do |k| 
     k.class == String && k =~ /^\w+$/ 
    end 

    WordPlay.best_sentence(input.sentences, hot_words) 
end 

def possible_responses(sentence) 
    responses = [] 

    # Find all patterns to try to match against 
    @data[:responses].keys.each do |pattern| 
     next unless pattern.is_a?(String) 

     # For each pattern, see if the supplied sentence contains 
     # a match. Remove substitution symbols (*) before checking. 
     # Push all responses to the responses array. 

     if sentence.match('\b' + pattern.gsub(/\*/, '') + '\b') 
      # If the pattern contains substitution placeholders, perform the substitutions 
      if pattern.include?('*') 
       responses << @data[:responses][pattern].collect do |phrase| 
        # Erase everything before the placeholder, leaving everything after it 
        matching_section = sentence.sub(/^.*#{pattern}\s+/, '') 
        # Then substitute the text after the placeholder with the pronouns switched 
        phrase.sub('*', Wordplay.switch_pronouns(matching_section)) 
       end 
      else 
       responses << @data[:responses][pattern] 
      end 
     end 
    end 

    # If there were no matches, add the default ones 
    responses << @data[:responses][:default] if responses.empty? 
    # Flatten the blocks of responses to a flat array 
    responses.flatten 
end 
end 

Файл каламбур:

class String 
def sentences 
    self.gsub(/\n|\r/, ' ').split(/\.\s*/) 
end 

def words 
    self.scan(/\w[\w\'\-]*/) 
end 
end 

class WordPlay 
def self.switch_pronouns(text) 
    text.gsub(/\b(I am|You are|I|You|Your|My|Me)\b/i) do |pronoun| 
     case pronoun.downcase 
     when "i" 
      "you" 
     when "you" 
      "me" 
     when "me" 
      "you" 
     when "i am" 
      "you are" 
     when "you are" 
      "i am" 
     when "your" 
      "my" 
     when "my" 
      "your" 
     end 
    end.sub(/^me\b/i, 'i') 
end 

def self.best_sentence(sentences, desired_words) 
    ranked_sentences = sentences.sort_by do |s| 
     s.words.length - (s.downcase.words - desired_words).length 
    end 

    ranked_sentences.last 
end 
end 

ответ

1

Язык рубина чувствителен к регистру с его переменными и константами.

Поэтому вам необходимо написать слово Wordplay так же, как и везде.

Я предлагаю написать class Wordplay с нижним регистром. Другим вариантом является написать другое происхождение с верхним регистром P, как предложил Грег Гида.

+0

Ах, вот где все пошло не так .. Спасибо за разъяснение. –

+0

добро пожаловать :) – scones

0

р в игре слов на строка 73 должна быть в верхнем регистре

+0

спасибо. Кажется, мне нужно больше внимания уделять верхнему/нижнему регистру в моем коде. –