除了散列作为最后一个参数之外,您可以在Ruby中删除方法调用中的括号并获得一致的结果(您仍然需要考虑优先级)。
但是,我遇到了一个不是这种情况的例子:
Zookeeper
这是一个错误/回归(我用2.1.2测试了它 - > 2.4.1 Rubys)?
还有其他一般情况下丢弃parens不能按预期工作吗?
Reported it,让我们看看。
更新:机票有点模糊不清。目前尚不清楚它是否是一个错误,但它不会得到修复,并建议在这些情况下使用''.split(/ ./) # => []
''.split /./ # => []
''.split / ./ # !> SyntaxError: unexpected '.'
。原因确实是开头的斜线被解释为分裂。
答案 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
,具体取决于变量的先前值。
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中以不止一种方式使用,因此可能还有许多模糊语法的例子。