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



这里有两行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

您的代码中是否有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空格字符的列表。

最新更新