0

目前正在阅读《Beginning Ruby》第 12 章,它构建了一个对话机器人。运行 basic_client.rb 文件时,机器人会加载。当给定输入“我讨厌电视”时,机器人应该识别带有“讨厌”一词的模式并根据该模式返回响应。

相反,它会从 bot 文件中返回一些名称错误。这些都与 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
4

2 回答 2

1

ruby 语言的变量和内容是区分大小写的。

因此,您需要在Wordplay任何地方使用相同的方式来编写单词。

我建议class Wordplay用小写 P 写。另一种选择是用大写 P 写另一个出现,就像 Greg Guida 建议的那样。

于 2013-04-04T06:14:09.890 回答
0

第 73 行文字游戏中的 p 应为大写

于 2013-04-04T05:44:09.120 回答