我可以避免在这个ruby函数中使用if-elsif-else吗?

我可以避免在这个ruby函数中使用if-elsif-else吗?,ruby,if-statement,control-flow,Ruby,If Statement,Control Flow,我有三个值(foo、bar、bad),根据这三个值传递给函数,我想使用另外两个 例如,调用self.method(foo)会导致类似这样的结果,foo未定义 def method self.foo = 180 - self.bar - self.bad end 我可以用一个简单的if-elsif-else设置来完成,但是有更好(更惯用)的方法吗 为清晰起见更新: 以下是一个建议在生产中可能会出现的情况: def solve_angles(missing) angles = 180 -

我有三个值(foo、bar、bad),根据这三个值传递给函数,我想使用另外两个

例如,调用
self.method(foo)
会导致类似这样的结果,
foo
未定义

def method
  self.foo = 180 - self.bar - self.bad
end
我可以用一个简单的if-elsif-else设置来完成,但是有更好(更惯用)的方法吗

为清晰起见更新:

以下是一个建议在生产中可能会出现的情况:

def solve_angles(missing)
  angles = 180 - [ A, B, C ].reject { |e| e == missing }.inject(:+)
end

通过
@triangle.solve_angles(self.C)
甚至'@triangle.solve_angles(“C”)调用都是可能的。

如果它只是基本的加法、乘法等,那么下面的内容就足够了,但不能保证更复杂

def method(input)
  self.foo + self.bar + self.bad - input
end
或者,您可以将它们全部放在一个数组中,并删除您提供的一个数组

def method(input)
  [self.foo, self.bar, self.bad].reject { |e| e==input }.inject { ... }
end

试试这样的东西:

def method(arg)
  [ bar, bad, foo ].reject { |e| e == arg }.inject(:+)
end

请注意,您不需要向
self
接收器发送信号,它是隐式的。

您不需要指定要求解的角度;这在问题的定义中是隐含的。如果您从以下内容开始(任何类似于错误处理的内容都被省略):

然后:

如有必要,还可以返回/指示实际求解的角度

这实际上并没有避免使用
if
语句,这是您的具体问题。这样就不需要明确地把每一个问题都说出来,我认为这是问题的目的

如果您确实需要“解决”,您可以添加:

def solve_for sym
  solve
  instance_variable_get("@#{sym}".to_sym)
end
从技术上讲,只有在确定值未设置,但meh后才能进行求解

> t = Triangle.new :a => 20, :c => 30
=> a=20, b=, c=30
> t.solve_for :b
=> 130
> t
=> a=20, b=130, c=30
> t = Triangle.new :a => 20, :c => 30
=> a=20, b=, c=30
> t.solve_for :a
=> 20
> t
=> a=20, b=130, c=30

以下是我提出的解决方案:

def solve_angles(missing)
      holder = [:A, :B, :C]
      holder.delete(missing)
      angle = 180 - (self.send(holder[0]) + self.send(holder[1]))
end
这是一个糟糕的解决方案吗?为什么?

或者,这是否更干净/更好

def solve_angles(missing)
  holder = [:A, :B, :C] - [missing]
  angle = 180 - send(holder[0]) - send(holder[1])
end
或:


这完全取决于;决策值是基于符号的,还是直接依赖于符号的?它总是有助于显示您到目前为止所写的内容,而不是让我们其他人尝试可视化您的代码并对其进行改进。我已经更新了代码,希望能使代码更具意义。它实际上是在尝试求解三个角度,其中两个已知,第三个丢失,但所有三个角度加起来必须为180。请注意,
delete
返回已删除的元素(或
nil
),因此第二个代码段不起作用。已更新。谢谢你的关注。我已经在上面添加了一些澄清。我想我是走错了路。这里有一些东西我不太明白它们是如何工作的。谢谢你这么做。我会玩弄它,以确保我了解它是如何工作的。我很感激你花了这么多时间在这上面。我不会说这是“坏的”,如果你有
attr\u accessor
s在它们上面,它看起来会工作得很好。我倾向于使用更通用的解决方案(而不是明确的三面)的一个原因是,它适合于其他形状,可以在运行时定义、填充、查询等。例如,
s=Shape.new(sides:5)
可以完成创建五边形所需的所有设置,包括计算内部角度总和、创建角度访问器等。
def solve_angles(missing)
      holder = [:A, :B, :C]
      holder.delete(missing)
      angle = 180 - (self.send(holder[0]) + self.send(holder[1]))
end
def solve_angles(missing)
  holder = [:A, :B, :C] - [missing]
  angle = 180 - send(holder[0]) - send(holder[1])
end
def solve_angles(missing)
  angles = [:A, :B, :C] - [missing]
  angles.inject(180) { |memo, a| memo - send(a) }
end