Ruby是否存在空格敏感场景?为何rand*10与rand * 10结果不同?
为什么Ruby中
rand *10和rand * 10返回不同结果? 这其实是Ruby语法解析规则里一个很典型的“空格影响语义”的例子,咱们结合你用Ripper拿到的结果来拆解清楚:
两种写法的本质差异
从你贴的Ripper.sexp结果就能看出核心区别:
rand *10被解析为带参数的方法调用:
这个表达式里,Ruby把rand当成接收参数的方法,*10是它的参数(这里的*是Ruby的splat操作符,作用是把单个值展开成方法的参数列表)。而Ruby的rand方法如果传入一个整数n,会返回0 <= x < n的整数,所以rand *10等价于rand(10),返回的是0到9之间的整数,你看到的结果1完全符合这个逻辑。rand * 10被解析为二元乘法运算:
当*前后都有空格时,Ruby会把它识别成乘法运算符。这个表达式的执行逻辑是:先调用无参数的rand方法(返回0到1之间的浮点数),再把这个浮点数和10相乘,所以得到的是类似2.7177这样的浮点结果。
为什么空格会造成这种差异?
Ruby允许省略方法调用的括号,这时候空格就成了解析器区分“方法参数”和“运算符”的关键:
- 当
*紧跟在方法名后的空格之后,且后面没有空格直接跟值时,解析器会把*xxx判定为方法调用的splat参数; - 当
*前后都有空格时,解析器会把它判定为独立的乘法运算符,把前后的内容当作两个独立的表达式来计算。
你用Ripper.lex拿到的token差异看似不大,但解析器正是通过*后面是否有空格这个细节,决定了它的语义——是作为方法参数的splat,还是作为乘法运算符。
内容的提问来源于stack exchange,提问作者user9726814
相关产品推荐
相关产品推荐

