Ruby / Rails 中的括号参数

parenthetical parameters in Ruby / Rails

学习 Ruby / Rails,并在使用 ERB 模板时遇到此问题:

作品:

<%= link_to image_tag(link.screenshot.url(:thumb)), link.screenshot.url(:original) %>

不起作用:

<%= link_to image_tag link.screenshot.url(:thumb), link.screenshot.url(:original) %>

在第一个中,image_tag 的参数在括号中。另一方面,他们不是。

我在 Ruby 中了解到,方法并不总是需要将它们的参数放在括号中,但在这种情况下,跳过它们的惯例似乎有问题。

随便处理? ERB模板的特殊性?还是我错过了更大的东西?

一如既往,谢谢。

在确定如何解释带省略括号的嵌套函数调用时,ruby 不查看方法签名以及它们允许的参数数量。相反,它只是遵循一组固定的优先级规则,在您的情况下,带括号和不带括号会导致不同的结果:

def a(*arguments)
  puts "a called with #{arguments.inspect}"
  return :a_result
end

def b(*arguments)
  puts "b called with #{arguments.inspect}"
  return :b_result
end

def c(*arguments)
  puts "c called with #{arguments.inspect}"
  return :c_result
end

def d(*arguments)
  puts "d called with #{arguments.inspect}"
  return :d_result
end

puts (a b(c(:foo)), d(:bar)).inspect
# c called with [:foo]
# b called with [:c_result]
# d called with [:bar]
# a called with [:b_result, :d_result]
# :a_result

puts (a b c(:foo), d(:bar) ).inspect
# c called with [:foo]
# d called with [:bar]
# b called with [:c_result, :d_result]
# a called with [:b_result]
# :a_result

因此,省略了 bs parens,该调用被解释为等同于

a(b(c(:foo), d(:bar)))

如果其中一个函数不允许这些数量的参数,该行将失败。更危险的是,当函数确实允许可变数量的参数时,就像我在此处的示例函数所做的那样,您将执行与您想象的不同的操作,并且可能只会在很久很久以后才注意到错误。

此示例中缺少括号表示解析此类表达式时存在问题。一般在Ruby中可以省略"how to pass arguments".

让我们考虑以下情况 - 我定义了 addmulti 方法:

def add(*args)
  args.inject(:+)
end

def multi(*args)
  args.inject(:*)
end

所以下面很清楚:

add 1, 2, 3, 4
# => 10

multi 1, 2, 3, 4
# => 24

但万一:

add 1, multi 2, 3, 4

预期的输出是什么?您可以考虑几个场景:

add(1, multi(2, 3), 4)
# => 11

add(1, multi(2, 3, 4))
# => 25

add(1, multi(2), 3, 4)
# => 10

使用括号时 - 您可以计算输出,因为您知道哪些参数用于哪种方法。如果不使用 - 你不能,所以 Ruby 也不能这样做。

让我们回到您提到的方法。 Ruby 不知道是否方法:

<%= link_to image_tag link.screenshot.url(:thumb), link.screenshot.url(:original) %>

应该像这样对待:

<%= link_to image_tag(link.screenshot.url(:thumb)), link.screenshot.url(:original) %>

或:

<%= link_to image_tag(link.screenshot.url(:thumb), link.screenshot.url(:original)) %>

希望它能对问题有所启发!

祝你好运!