ruby - 将参数传递给 Ruby 方法
问题描述
似乎可以通过在方法之后附加参数并将两者用空格分隔来将参数传递给某些 Ruby 方法。我试图了解使这种情况发生的机制。这就是在命令行中将参数传递给脚本的方式。为什么以下语句在 Ruby 中有效?
item = 'orange'
fruits = ['orange', 'grapefruit', 'apple']
x = fruits.include? item
puts x
为什么以下语句不起作用?
item = 'orange'
fruits = ['orange', 'grapefruit', 'apple']
x = fruits.include? item ? 'You picked a fruit' : 'You did not pick a fruit'
puts x
解决方案
使用 Ripper 检查 AST
在 Ruby 中,括号在很大程度上是可选的,除非需要避免歧义,例如将参数传递给采用块的方法时。在底层,主线 Ruby 有很多可移动的部分,用于标记和解析您编写的代码。最有用的模块之一是Ripper 模块(在此处记录),它使您能够查看 Ruby 从您的代码中生成的抽象语法树。
这是 Ruby 看到的两个版本的代码。您可以从 S 表达式中看到失败版本与非失败版本不同。在 irb 中:
Ripper.sexp %q{x = fruits.include?(item) ? 'You picked a fruit' : 'You did not pick a fru
it'}
#=>
[:program,
[[:assign,
[:var_field, [:@ident, "x", [1, 0]]],
[:ifop,
[:method_add_arg,
[:call,
[:vcall, [:@ident, "fruits", [1, 4]]],
[:@period, ".", [1, 10]],
[:@ident, "include?", [1, 11]]],
[:arg_paren, [:args_add_block, [[:vcall, [:@ident, "item", [1, 20]]]], false]]],
[:string_literal, [:string_content, [:@tstring_content, "You picked a fruit", [1, 29]]]],
[:string_literal, [:string_content, [:@tstring_content, "You did not pick a fruit", [1, 52]]]]]]]]
Ripper.sexp %q{x = fruits.include? item ? 'You picked a fruit' : 'You did not pick a frui
t'}
#=>
[:program,
[[:assign,
[:var_field, [:@ident, "x", [1, 0]]],
[:command_call,
[:vcall, [:@ident, "fruits", [1, 4]]],
[:@period, ".", [1, 10]],
[:@ident, "include?", [1, 11]],
[:args_add_block,
[[:ifop,
[:vcall, [:@ident, "item", [1, 20]]],
[:string_literal, [:string_content, [:@tstring_content, "You picked a fruit", [1, 28]]]],
[:string_literal, [:string_content, [:@tstring_content, "You did not pick a fruit", [1, 51]]]]]],
false]]]]]
由于 Ruby 将几乎所有内容都视为返回值的表达式,因此操作顺序会影响解析器如何形成表达式。三元运算符最终必须评估为三个表达式,如果您使用解析器认为不明确的语法,则会导致问题。
也可以看看
推荐阅读
- reactjs - onClick Jest / 酶:方法“模拟”意味着在 1 个节点上运行。找到了 0 个
- python - 如何使用 python 和 selenium webdriver 遍历表并打印前 10 行的结果?
- python-3.x - 如何检查布尔熊猫系列中的所有值是否属于一种类型并根据if条件应用逻辑?
- java - android app下载apk文件并打开(安装)
- go - Golang:用于重新连接 TCP 客户端的递归函数......坏主意?
- python - 如何根据数独条件删除字典值删除错误值?
- python - 在数组数组中查找所有可能的项目组合
- java - 我在 println 中不断收到“错误:找不到符号”
- dart - Flutter:在 StatelessWidget 中哪里添加监听器?
- excel - Excel/Sheets 根据相邻单元格添加和列出单元格值