发现Ruby语法错误:NameError:未定义的局部变量或方法`'

时间:2013-06-29 21:39:46

标签: ruby ruby-2.0

以下是两行Ruby,用于检查数组中有多少项是“有效”或“无效”:

valid = cr.select { |x| x.valid? }.count
invalid = cr.select { |x| !x.valid? }.count

有人能发现第二行有语法错误的原因吗?我已在调试器中逐步执行此代码,并在尝试执行invalid = ...行时引发异常。两行之间的唯一区别是!,我检查过!true == false是否有效。我很难过。


这是整个代码文件:

require "colored"

require "address_kit/cli/interactive/command"
require "address_kit/cli/interactive/shell"

module AddressKit
  module CLI
    module Interactive
      module Commands

        class TableValidationStats < TableCommand
          NAME = "table_validation_stats"
          SUMMARY = "Displays statistics about the table address validation"
          HELP_TEXT = <<-TEXT.chomp.reset_indentation
            This command displays how many rows that has been validated, how
            many of those rows were valid, invalid or auto-corrected.
          TEXT

          def execute(context, args)
            super

            shell = context.shell
            results = context.vars[:address_processing_results] || []

            if results.length < 1
              shell.puts_padded "No rows have been processed"
              return
            end

            require "byebug"; byebug

            cr = results.compact
            total_processed = cr.count
            failed_parsing = cr.select { |x| !x.parsed? }.count
            valid = cr.select { |x| x.valid? }.count
            invalid = cr.select { |x| !x.valid? }.count
            corrected = cr.select { |x| x.corrected? }.count

            shell.puts
            shell.puts "Rows processed: #{total_processed.to_s.bold}"
            shell.puts "Parse failures: #{failed_parsing.to_s.bold}"
            shell.puts "Valid addresses: #{valid.to_s.bold}"
            shell.puts "Invalid addresses: #{invalid.to_s.bold}"
            shell.puts "Addresses auto-corrected: #{corrected.to_s.bold}"
            shell.puts
          end
        end

        Shell.register_command TableValidationStats

      end
    end
  end
end

这是堆栈跟踪的错误(忽略额外的文本,我的项目手动打印错误信息):

  AN ERROR HAS OCCURRED!

  The command you just ran produced an unexpected error.
  Your shell session will not be lost, but please report
  the following text to the maintainer of this project:

  Exception: NameError
  Message: undefined local variable or method ` ' for #<AddressKit::CLI::Interactive::Commands::TableValidationStats:0x00000001a6b840>

  Stack trace:
  /home/tomas/Dropbox/Kvantel/Address Kit/lib/address_kit/cli/interactive/commands/table_validation_stats.rb:37:in `block in execute'
  /home/tomas/Dropbox/Kvantel/Address Kit/lib/address_kit/cli/interactive/commands/table_validation_stats.rb:37:in `select'
  /home/tomas/Dropbox/Kvantel/Address Kit/lib/address_kit/cli/interactive/commands/table_validation_stats.rb:37:in `execute'
  /home/tomas/Dropbox/Kvantel/Address Kit/lib/address_kit/cli/interactive/shell.rb:82:in `shell_iteration'
  /home/tomas/Dropbox/Kvantel/Address Kit/lib/address_kit/cli/interactive/shell.rb:46:in `start'
  bin/address_kit_shell:42:in `<main>'

变量crAddressProcessingResult个对象的数组。它们看起来像这样:

module AddressKit

  # This class represents the end result of the processing of an address,
  # including normalization, parsing, validation and correction.
  class AddressProcessingResult
    attr_accessor :original_address, :parsed_address, :corrected_address, :note
    attr_writer :parsed, :validated, :valid, :corrected

    def initialize(original_address = nil)
      @original_address = original_address
      @parsed_address = nil
      @corrected_address = nil
      @note = ""
      @parsed = false
      @validated = false
      @valid = false
      @corrected = false
    end

    def parsed?; @parsed; end
    def validated?; @validated; end
    def valid?; @valid; end
    def corrected?; @corrected; end

    def readable_summary
      if not parsed?
        "Failed to parse address: #{@original_address}"
      elsif valid?
        "Address is valid: #{@parsed_address}"
      elsif corrected?
        "Address was auto-corrected: #{@corrected_address}: #{@note}"
      else
        "Address was invalid and could not be corrected: #{@corrected_address}"
      end
    end
  end

end

1 个答案:

答案 0 :(得分:9)

您的代码中是否有Unicode空格字符(作为其他地方的复制粘贴的结果)? Ruby会将其解释为有效的变量名称!证明:

script = <<-EOF
  #{"\u00A0"} = "foo"
  puts #{"\u00A0"}
EOF

puts "The contents of the script are:"
puts script

puts "The output of the script is:"
eval script

输出:

The contents of the script are:
    = "foo"
  puts  
The output of the script is:
foo

我会使用十六进制编辑器或其他一些擦除器检查源代码中的unicode字符。我可以像这样生成相同的错误消息:

> eval "puts #{"\u00A0"}"
NameError: undefined local variable or method ` ' for main:Object

您可以扫描文件中的非ASCII字符,如下所示:

def find_nonascii(file)
  p_line = 1; p_char = 0
  open(file, "r").each_char do |char|
    if char.ord == 10
      p_line += 1
      p_char = 0
    end
    p_char += 1
    puts "Found character #{char.ord} (#{char.inspect}) at line #{p_line}, character #{p_char}" if char.ord > 126
  end
end

这将为您提供脚本中第一个非ascii字符的位置。

您可以找到Unicode空格字符列表here