p "4".to_i +3 # => 0 这个结果很费解,竟然不是 7
p "4".to_i + 3 # => 7
p 4 +3 # => 7
p 4 + 3 # => 7
如果不开终端确认,第一个结果我就搞错了。我知道这是错误的省略空格导致的歧义,可是为什么会得零? 尝试获取语法树的结果:
require 'parser/current'
# opt-in to most recent AST format:
Parser::Builders::Default.emit_lambda = true
Parser::Builders::Default.emit_procarg0 = true
Parser::Builders::Default.emit_encoding = true
Parser::Builders::Default.emit_index = true
pp Parser::CurrentRuby.parse('"4".to_i +3')
pp Parser::CurrentRuby.parse('"4".to_i + 3')
pp Parser::CurrentRuby.parse('"4".to_i +3').loc
pp Parser::CurrentRuby.parse('"4".to_i + 3').loc
输出为
s(:send,
s(:str, "4"), :to_i,
s(:int, 3))
s(:send,
s(:send,
s(:str, "4"), :to_i), :+,
s(:int, 3))
#<Parser::Source::Map::Send:0x00007f9ff589c348
@begin=nil,
@dot=#<Parser::Source::Range (string) 3...4>,
@end=nil,
@expression=#<Parser::Source::Range (string) 0...11>,
@node=s(:send,
s(:str, "4"), :to_i,
s(:int, 3)),
@selector=#<Parser::Source::Range (string) 4...8>>
#<Parser::Source::Map::Send:0x00007f9ff78428c8
@begin=nil,
@dot=nil,
@end=nil,
@expression=#<Parser::Source::Range (string) 0...12>,
@node=s(:send,
s(:send,
s(:str, "4"), :to_i), :+,
s(:int, 3)),
@selector=#<Parser::Source::Range (string) 9...10>>
没看出操作符是怎么丢失的,再底层一些:
require 'ripper'
pp Ripper.sexp '"4".to_i + 3'
pp Ripper.sexp '"4".to_i +3'
输出为:
[:program,
[[:binary,
[:call,
[:string_literal, [:string_content, [:@tstring_content, "4", [1, 1]]]],
:".",
[:@ident, "to_i", [1, 4]]],
:+,
[:@int, "3", [1, 11]]]]]
[:program,
[[:command_call,
[:string_literal, [:string_content, [:@tstring_content, "4", [1, 1]]]],
:".",
[:@ident, "to_i", [1, 4]],
[:args_add_block, [[:@int, "+3", [1, 9]]], false]]]]
仍然没看出为何会得零?