【问题标题】:parenthetical parameters in Ruby / RailsRuby / Rails中的括号参数
【发布时间】:2015-07-30 11:20:15
【问题描述】:

学习 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 模板的特殊性?还是我错过了更大的东西?

一如既往,谢谢。

【问题讨论】:

  • 在此处查看答案stackoverflow.com/questions/6203585/…。本质上,当您有多个嵌套方法(本例中为link_toimage_tag)时,Rails 需要括号来知道哪些参数与哪些方法一起使用。

标签: ruby-on-rails ruby methods syntax parameters


【解决方案1】:

在确定如何解释带有省略括号的嵌套函数调用时,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 括号后,调用等效于

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

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

【讨论】:

    【解决方案2】:

    此示例中缺少括号表示解析此类表达式时存在问题。通常,在 Ruby 中,当明确“如何传递参数”时,您可以省略它们。

    让我们考虑以下情况 - 我定义了 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 不知道 if 方法:

    <%= 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)) %>
    

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

    祝你好运!

    【讨论】:

    • 把我脑海中开始形成的东西弄清楚了,谢谢!
    猜你喜欢
    • 2013-05-08
    • 2010-09-30
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多