2013-06-29 1 views
2

Вот две строки Руби, которая проверяет, сколько элементов в массиве является„действительным“или„недействительным“:Пятна ошибка рубина Синтаксис: NameError определено локальные переменный или метод ` '

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

показать нам ошибку..пожалуйста –

+0

что есть * cr *? –

+0

@Priti: Это было глупо со мной. Я предположил, что это была простая и легко продуманная синтаксическая ошибка, поэтому я не стал включать что-либо еще. Я сейчас редактировал этот вопрос. – Hubro

ответ

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 

Я хотел бы использовать шестнадцатеричный редактор или какой-либо другой скруббер, чтобы проверить юникод символов в исходном коде. Я могу производить такое же сообщение об ошибке, как так:

> 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 символа в скрипте.

Вы можете найти список символов пространства Юникода here.

+0

Я обновил вопрос. – Hubro

+0

И обновил мой ответ. –

+1

Почему вы предполагаете, что конец строки будет символом '\ r'? ('13.chr ==" \ r "') –