【问题标题】:Ruby min max assignment operatorsRuby 最小最大赋值运算符
【发布时间】:2012-02-26 02:32:48
【问题描述】:

在编写 ruby​​ 时,我总是发现自己在这样做:

a = [a, b].min

这意味着比较ab 并将最小值存储在a 中。我不喜欢写上面的代码,因为我必须写两次a

我知道 C++ 的一些非标准方言有一个操作符正是这样做的

a <?= b

我觉得这很方便。但我对运算符的兴趣并不像我对 避免重复的功能 那样感兴趣。如果我能写我也很高兴

a.keep_max(b)

a 可以是一个很长的变量,比如my_array[indice1][indice2],你不想写两次。

我对此做了很多谷歌搜索,但没有找到任何结果,希望这个问题会弹出并对其他人有用。

那么,有没有什么非重复的方式可以用 ruby​​ 表达我想要的东西?

【问题讨论】:

  • IMO 重新绑定值(没有很好的理由这样做)是一个糟糕的选择,只需创建一个具有不同名称的新变量。想一想:现在a 的值为 2,现在一些魔法,a 的值为 1……那种代码更难理解和调试。但是,当然,我是一个功能性偏执狂;-)
  • @tokland,也许是的。但是对于典型的动态编程代码,比如 floyd-warshall,您通常会完全按照我所说的去做。毕竟,所有的任务都是命令式语言的力量。
  • 很公平,当您在命令式循环中时,您别无选择,只能重用变量名(我猜该算法的功能实现在 Ruby 中可能效率低下)。我的笔记只是为了防止懒惰的编码,因为它重用了变量名。
  • @tokland,是的。你说的完全正确。我是 haskell 的粉丝,但我相信作业并不总是邪恶的!此外,ruby 并不是主要为功能风格而设计的(afaik)。

标签: ruby variable-assignment max assignment-operator min


【解决方案1】:

实际上,你想做的事情在 ruby​​ 中是不可能的 (see this question)。我认为你能做的最好的就是

def max(*args)
  args.max
end

a = max a, b

【讨论】:

  • 正确的答案似乎确实是没有eval 技巧是不可能的(另一个问题提到了,感谢@kentor)。
【解决方案2】:

我不明白你的问题。你总是可以做这样的事情......

module Comparable
  def keep_min(other)
     (self <=> other) <= 0 ? self : other
  end

  def keep_max(other)
     (self <=> other) >= 0 ? self : other
  end
end

1.keep_min(2)
=> 1

1.keep_max(2)
=> 2

嗯,这不适用于具有 的所有对象,因为并非所有对象都实现了 Comparable,因此您可以猴子修补对象。

就我个人而言,我更喜欢清晰,并倾向于避免猴子修补。另外,这显然是一个二进制谓词,就像“+”一样,因此方法链接不一定有意义,所以我更喜欢这样的东西来摆脱那种数组语法:

def min(*args)
   args.min
end

def max(*args)
   args.max
end

min(1, 2)
=> 1

max(1, 2)
=> 2

但是,嘿,我也是一名 Python 开发人员 :-)

【讨论】:

    【解决方案3】:

    您可以为它定义自己的方法:

    class Object
      def keep_max(other)
        [self, other].max
      end
    end
    
    a = 3
    b = 7
    puts a.keep_max(b)
    

    但是你应该小心定义 Object 的方法,因为它可能有不可预知的行为(例如,如果对象无法比较)。

    【讨论】:

      【解决方案4】:
      def keep_max(var, other, binding)
        eval "#{var} = [#{var}, #{other}].max", binding
      end
      
      a = 5 
      b = 78
      keep_max(:a, :b, binding)
      puts a
      #=> 78
      

      这基本上可以满足您的需求。看看Change variable passed in a method

      【讨论】:

      • evalbinding 对于 keep_max,我不建议这样做
      猜你喜欢
      • 2015-03-02
      • 2012-01-24
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 2013-02-27
      • 2010-11-24
      • 2016-11-04
      • 2011-08-02
      相关资源
      最近更新 更多