【问题标题】:How default parameters are interpreted when default values are empty hashes默认值为空哈希时如何解释默认参数
【发布时间】:2018-10-16 05:01:02
【问题描述】:

我正在阅读这个 SO 问题:https://stackoverflow.com/a/4402761/2379703,最后一篇显示 rails render impl 的帖子很有趣。它的签名是:

def render(options = {}, locals = {}, &block)

如果第一个参数是纯字符串,它会将其分配给选项,其余的被解释为哈希并分配给本地变量。例如:

render('partial_name', key: 'value', key2:, 'value2')

结果:

options = "partial_name"
locals = {key: 'value', key2:, 'value2'}

如果你只是传递键/值对,它假定你传递了一个散列的单个参数并将其全部分配给选项并将局部变量留空:

render(partial: 'partial_name', key: 'value', key2", 'value2')

结果:

options = {partial: 'partial_name', key: 'value', key2:, 'value2'}
locals = {}

所以我的问题真正归结为:当有多个可选参数时,ruby 用来确定分配哪个参数的逻辑是什么?此外,哈希似乎使这个问题的答案更有趣,因为当作为参数传入时,哈希显然不需要用外部 {} 分隔。

次要观察,在一个测试中,我对像渲染这样的测试方法使用了相同的签名,并且我传递了以下内容:

render(key: 'value', key2: 'value2', 'string')

这会导致语法错误:

test_hash_param.rb:15: syntax error, unexpected ')', expecting =>

这是为什么?为什么不将两个键/值对分配给选项并将本地设置为'string'?

然而,这就像我想象的那样工作:

render({key: 'value', key2: 'value2'}, 'string')

【问题讨论】:

    标签: ruby-on-rails ruby hash


    【解决方案1】:

    首先,您只能将不带{} 括号的哈希作为该方法的最后一个参数传递。否则解释器将很难找出一个参数在哪里结束而另一个参数在哪里开始。

    话虽如此,当 ruby​​ 在参数列表的末尾看到类似哈希的参数列表时,它将始终将其视为单个哈希。因此,在您的示例中,只有选项已分配值,因为尚未传递 locals 并且已使用默认值。你可以在这里找到很多关于 stackoverflow 的问题。如果你需要传递两个单独的哈希,你需要将它们中的至少第一个括在括号中(如果它不是最后一个参数,自然也包括第二个)

    【讨论】:

    • 好吧,我错过的关键花絮是“你只能在没有 {} 作为最后一个参数的情况下传递哈希”。话虽如此,现在所有的行为都是有意义的:)。谢谢。
    【解决方案2】:

    因为您正在无边界地传递哈希,所以 ruby​​ 必须决定如何解释它们。与其选择任意位置将您的键:值对分成两个散列,不如将它们全部分组到一个散列中。这意味着:

    render( foo: "bar", hello: "world", "bananas")

    被读取为一个哈希,因为它无法告诉您要在哪里结束哈希。 'bananas' 被包含为键(因为字符串可以是键)并弹出语法错误,因为您没有为其分配值。

    但选项和局部变量不必是哈希值,因为 ruby​​ 变量类型是动态的。它们的默认值为空哈希,但如果您传递两个字符串,它们都将被分配字符串。当您传递一个字符串时,它被分配给选项,因为它是一个完整的变量。当你传递一个符号/字符串和一个散列火箭(或一个冒号翻转的符号)时,你告诉 ruby​​ “这是散列的开始”,所以它开始寻找键:值对。为了在您的参数结束之前结束该哈希以便您可以传递另一个参数,您必须明确告诉 ruby​​ 停止寻找键:值对。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 2010-09-18
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多