Ruby - 使用语法糖括号方法返回二维数组中的值

时间:2016-09-25 22:33:41

标签: ruby

令我困惑的一个基本例子:

def [](row, col)
  self[row][col]
end

x = [[1,3], [4,5]]
x[0][0] #normal
x[0, 0] #syntactic sugar?

我被告知这些是等同的陈述,但当我运行糖时,我会得到一个不同的答案。我怎么能用语法糖写它?

2 个答案:

答案 0 :(得分:3)

您需要将$ irb 2.3.0 :001 > class MyData 2.3.0 :002?> attr_accessor :my_array 2.3.0 :003?> def [](row, col) 2.3.0 :004?> my_array[row][col] 2.3.0 :005?> end 2.3.0 :006?> end => :[] 2.3.0 :007 > x = MyData.new => #<MyData:0x007f96dc8024b8> 2.3.0 :008 > x.my_array = [[1, 3], [4, 5]] => [[1, 3], [4, 5]] 2.3.0 :009 > x[1,1] => 5 2.3.0 :010 > 方法放在包含数据的类中。如下所示:

@media (-ms-high-contrast: none), (-ms-high-contrast: active) {
 .yourTargetClass:before {
    content: "";
    position: absolute;
    height: 100%;
    width: 100%;
    background-image: linear-gradient(-221deg, rgba(205,234,255,0.41), rgba(227,253,255,0.82)); /* THIS IS WHAT EVER OVERLAY COLOUR YOU WANT */ }
    opacity:0.55;
  }
}

答案 1 :(得分:1)

这有两个问题:

  1. 您正在将方法添加到Object课程。但是Array有自己的[]会覆盖Object中的那个,所以你的方法永远不会被调用...
  2. ...这是一件好事,因为它无论如何都不起作用:所有方法都是调用自身,导致堆栈溢出,因为失控的递归,但幸运的是,方法调用它本身带有一个参数,但被定义为采用两个参数,因此你得到的只是ArgumentError
  3. 现在,忘记修补核心课程的那一刻是可怕的想法,你可以到这个:

    module TwoDArrayExtension
      def [](x, y)
        super(x).method(__callee__).super_method.(y)
      end
    end
    
    class Array
      prepend TwoDArrayExtension
    end
    
    x = [[1, 3], [4, 5]]
    
    x[0][0] #normal
    # in `[]': wrong number of arguments (given 1, expected 2) (ArgumentError)
    # Hey, we just re-defined [] to take two arguments, so obviously this cannot work!
    
    x[0, 0] #syntactic sugar?
    #=> 1
    

    这“工作”意味着它会让你的语法糖示例通过。但是您的“正常”示例现在已经破坏:您已经重新定义了数组的工作方式,因此您不能再像数组一样使用它。修补像这样的核心课程有严重的后果。例如:

    • Irb是用Ruby编写的,除了其他内容之外还使用内部数组。你无法在Irb中测试你的代码,因为它会崩溃。
    • 同样适用于Pry。
    • 这同样适用于使用数组的任何和所有现有代码......这几乎都是所有编写的Ruby代码。你不能使用任何宝石。您不能使用和标准库。
    • 事实上,在像Rubinius这样的实现中,几乎所有所有,包括核心库本身的大部分,甚至编译器都是用Ruby编写的,因此在内部使用数组,你可能赢了甚至无法让你的代码运行。

    简而言之:是的,你可以这样做,但你真的,真的真的真的不想。< / p>