以下是两行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
答案 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。