强制设置方法的默认值

7

给定以下方法:

def foo(a,b=5,c=1)
    return a+(b*c)
end

运行foo(1)应该返回6。然而,如果这样写:foo(1,默认值,2),我该怎么做才能更改第三个值但仍使用默认的第二个值呢?
请问应该如何操作?(注意:我不能只更改变量的顺序,因为它们是来自gem方法的参数。)

无法完成。请使用命名参数。foo(1) #=> 5 - Cary Swoveland
嗯,是的,#=> 6(我以为它是a*(b*c)。) - Cary Swoveland
请澄清您所说的无法更改变量顺序的含义。 - Cary Swoveland
@CarySwoveland 这是来自一个 gem 的方法。 - notme1560
2个回答

11

根据问题的条件,您不能按照所提出的方式完成。这正是 Ruby 2 中引入命名(关键字)参数的原因。但是,根据问题的要求,具有默认值的参数不是命名参数。

因此,它们是位置参数——这就是为什么可选参数必须放在最后的原因,并且规则是,必须使用至少一个参数调用此方法(因为 a 不是可选参数),并且任何进一步的参数将按照提供的顺序用于填充相应的参数。

因此,您可以提供 aababc。如果这些参数是命名参数,则不能仅提供 ac

因此,有两个明显的解决方案。

  • 调用该方法,并将第二个参数的默认值作为第二个参数提供。您可能已经知道它是什么,所以这不是太麻烦:
  • foo(1,5,2)
    
  • 编写一个跳板函数(trampoline method),与之前的函数相同,但参数 已命名

    def foo(a,b=5,c=1)
      return a+(b*c)
    end
    def bar(a,b:5,c:1)
      return foo(a,b,c)
    end
    bar(1,c:2) # => 11
    

1
这是一个巧妙的技巧,但如果 foo 的默认值发生更改,那么这个包装方法也必须进行更改。 - tadman

2

一种解决方案是默认为 nil,然后在代码体中进行默认值设置:

def foo(a,b=nil,c=nil)
  b ||= 5
  c ||= 1

  a + (b * c)
end

您可以将其作为计算的一部分进行:

def foo(a,b=nil,c=nil)
  a + (b || 5) * (c || 1)
end

2
但我认为暗示是foo的定义不由他决定。 - matt
1
@Punknoodles 你有点卡住了。一般来说,我们无法知道默认值是什么。我建议手动提供它所期望的默认值。 - tadman
@tadman,是的,我刚意识到我使用的值已经过时了。现在他们使用选项哈希。这种方式运作得更好。 - notme1560
@Punknoodles 我认为你已经发现了他们为什么要切换的原因。如果需要跳过参数,使用哈希选项的方法更有意义。 - tadman
我想知道为什么他们不改用命名参数,除非这与旧版本的Ruby兼容有关。 - Cary Swoveland
很多旧的库(例如Rails)使用传统哈希而不是关键字参数,尽管在实践中这两个东西基本上是相同的。这更多是一种风格上的处理方式而不是技术上的处理方式。通常当你真正使用代码时,你会发现你的可选参数实际上是挑选的,而不是像你最初想象的那样按顺序排列的。 - tadman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接