2

下面是两行 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>'

变量cr是一个AddressProcessingResult对象数组。它们看起来像这样:

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
4

1 回答 1

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 空格字符列表。

于 2013-06-29T21:44:41.997 回答