parens的语法错误

时间:2017-03-27 12:48:49

标签: ruby

除了散列作为最后一个参数之外,您可以在Ruby中删除方法调用中的括号并获得一致的结果(您仍然需要考虑优先级)。

但是,我遇到了一个不是这种情况的例子:

Zookeeper

这是一个错误/回归(我用2.1.2测试了它 - > 2.4.1 Rubys)?

还有其他一般情况下丢弃parens不能按预期工作吗?

Reported it,让我们看看。

更新:机票有点模糊不清。目前尚不清楚它是否是一个错误,但它不会得到修复,并建议在这些情况下使用''.split(/ ./) # => [] ''.split /./ # => [] ''.split / ./ # !> SyntaxError: unexpected '.' 。原因确实是开头的斜线被解释为分裂。

3 个答案:

答案 0 :(得分:19)

除了thesecretmaster's answer之外,让我们来看看Ruby解析器:

require 'ripper'
require 'pp'

pp Ripper.lex("''.split /./")
# [[[1,  0], :on_tstring_beg,     "'"    ],
#  [[1,  1], :on_tstring_end,     "'"    ],
#  [[1,  2], :on_period,          "."    ],
#  [[1,  3], :on_ident,           "split"],
#  [[1,  8], :on_sp,              " "    ],
#  [[1,  9], :on_regexp_beg,      "/"    ],
#  [[1, 10], :on_tstring_content, "."    ],
#  [[1, 11], :on_regexp_end,      "/"    ]]

添加空格使Ruby将/字符识别为除法运算符:

pp Ripper.lex("''.split / ./")
# [[[1,  0], :on_tstring_beg, "'"    ],
#  [[1,  1], :on_tstring_end, "'"    ],
#  [[1,  2], :on_period,      "."    ],
#  [[1,  3], :on_ident,       "split"],
#  [[1,  8], :on_sp,          " "    ],
#  [[1,  9], :on_op,          "/"    ],
#  [[1, 10], :on_sp,          " "    ],
#  [[1, 11], :on_period,      "."    ],
#  [[1, 12], :on_op,          "/"    ]]
  

还有其他一般情况下丢弃parens不能按预期工作吗?

受挫的例子:

def foo(i = 1)
  10 * i
end

foo(- 2) #=> -20
foo - 2  #=> 8

另一个:

b = 2
def a(arg)
  arg
end

a *b    #=> 2

a = 5

a *b    #=> 10

第一个a *b被解释为a(*b),而第二个变为a * b。添加括号会强制Ruby调用方法:

a(*b)   #=> 2

答案 1 :(得分:9)

虽然这看起来确实是一个问题,但它并不是一个非常重要的问题,因为正则表达式中的$.ajax({ url: "/api/devices/sessions/overall/year/", type: "get", xhrFields: { withCredentials: true }, error: function(XMLHttpRequest, textStatus, errorThrown){ response({'error': XMLHttpRequest.status, 'error_description': XMLHttpRequest.statusText}) }, success: function(result) { if(result.error) { $('#yearly_action').show(); $('#yearly_action').html('<i class="fa fa-close"></i><br />Error loading yearly charts, please try again'); } else { $('#yearly_action').hide(); $('#yearly_chart').attr('style', ''); sessionsYearlyChart.data.datasets[0].data = []; Object.keys(response.summary).forEach(function(data) { sessionsYearlyChart.data.datasets[0].data.push(response.summary[data].count); }) sessionsYearlyChart.update(); } } }) 会捕获空格。例如:

\s

或者,如果你只想匹配一个空间,你必须正确地逃避它:

''.split(/ ./) # => []
''.split /./   # => []
''.split / ./  # !> SyntaxError: unexpected '.'
''.split /\s./ # => []

Ruby应该在parens内部或外部解析相同的参数,所以我提交了一个bug,但它并不是非常紧急,而且红宝石的人可能会很乐意离开它。

实际上,@ Stefan在评论中提到它可能是解析器将其视为devision,这是最可能的解释,所以它甚至都不是bug。但它是那些有趣的小红宝石怪癖之一。

@Stefan还补充说,您可以使用''.split /\ ./ # => [] 语法创建一个明确的正则表达式文字。

答案 2 :(得分:9)

分区或正则表达式?

正如在@ Stefan的answer中所写,Ruby试图将其解析为分裂。

但是如果没有parens,就很难区分和正则表达式。

例如,Ruby如何解析:

a /b/i

令人惊讶的是,无论是作为一个部门还是正则表达式,取决于具体情况。

def a(object)
  puts object.class
end
b = 4
i = 3

a /b/i
# Regexp

a = 24
a /b/i
# 2

如果a在作为方法之前被定义为变量,则脚本将引发NameError:

a = 24
def a(object)
  puts object.class
end
a(/b/i)
#Regexp
a /b/i
# 5:in `<main>': undefined local variable or method `b' for main:Object (NameError)

我说解析背后的模糊逻辑会使一些错误或令人惊讶的结果无法避免。

%:字符串分隔符或模数?

这是一个类似的例子,这次是%q。它是字符串分隔符还是modulo q

def a(x)
  puts x
end

a(%q+t+)
# t
a %q+t+
# t

a = 4
def a(x)
  puts x
end

a(%q+t+)
# t
a %q+t+
# syntax error, unexpected end-of-input

这可能是我第一次看到SyntaxError,具体取决于变量的先前值。

&安培; :Proc-&gt; Block,Bitwise AND或set intersection?

a &b可以至少以3种不同的方式解释:

def a
  yield
end

b = ->{ puts "BLOCK" }

a &b
# BLOCK

a = 3
b = 5
a &b
# 1

a = [1,2,3]
b = [3,4,5]
a &b
# [3]

许多符号在Ruby中以不止一种方式使用,因此可能还有许多模糊语法的例子。