使用initialize定义带参数的类方法

时间:2013-08-16 20:59:31

标签: ruby arrays class methods

我是红宝石的新手。我为一个问题编写了以下代码。我相信这段代码是正确的。

class Array 
  def sum
    result = 0
    self.each do |x|
      result += x
    end
    result
  end
end

我想知道的是如何在.self方法中不使用sum方法编写确切的代码。这是我想要做的......我知道下面的代码是不正确的,但它会告诉你我想要的东西。

class Array
  def initialize
    @array = []
  end

  def sum (@array)
    result = 0
    @array.each do |x|
      result += x
    end
    result
  end
end

所以我要做的是通过在sum方法中传递参数而不使用.self方法来使代码工作。有帮助吗?谢谢!

4 个答案:

答案 0 :(得分:1)

下面怎么样?

class Array
  def sum
    inject(0,:+)
  end
end
[2,9].sum # => 11

没有自我:(不是一个好的代码,而是使用上面的代码)

class Array
  def sum
    result = 0
    each do |x|
        result += x
    end
    result
  end
end
[1,1].sum # => 2

答案 1 :(得分:1)

在Ruby中,如果你不使用self,那么就暗示了自我。我将以您的代码为例。

在您的代码中,键入self.each。如果您只是简单地写了each,它也会起作用。您的代码片段如下所示:

def sum
  result = 0
  each do |x|
    result += x
  end
  result
end

这将以同样的方式工作。

[1,2,3,4].sum
#=> 10

为什么呢?在这种情况下,[1,2,3,4]self,并且由于each是一种方法,未​​在任何内容上调用,因此隐含self并且您的代码被解释为就像您说self.each。请注意,在这种情况下,您需要输入self.each,因为它对读者更有意义。因此,你把它写在最上面的方式是最好的。

如果我是你,我现在会探索inject。您可以通过调用inject方法来执行您的方法所做的事情:

[1,2,3,4].inject { |accum, elem| accum + elem }
#=> 10

更好,

[1,2,3,4].inject(:+)
#=> 10

我将留给你探索Ruby的深度,这个非常有趣的方法,以及inject(:+)如何工作。注意:在互联网上阅读时,:inject:reduce是相同的。就像数组的:count:length一样。 我将 : 放在他们面前作为 inject(:+)的提示。

答案 2 :(得分:1)

  

所以我要做的是通过在sum方法中传递参数而不使用.self方法来使代码工作。有什么帮助吗?

我相信你真的很困惑。至少有两种方法(我希望你关注):

  • 实例方法
  • 免费方法(Kernel类中定义的方法)

在你的情况下,你真正想要的是一个免费的方法(从Array类中解放),可以像这样定义:

def sum(array)
    array.reduce(:+)
end

并使用如下:

sum([1, 2, 3])
# => 6

我建议您使用实例方法版本:

class Array
    def sum
        reduce(:+)
    end
end

并使用它:

[1, 2, 3].sum
# => 6

答案 3 :(得分:0)

我不得不说你实际上想要使用自我而不是排除它。据我所知,在实例方法中使用self是首选实践。至于你的求和方法,我可能会这样写:

class Array
  def sum
    total = 0.0
    self.each {|x| total += x if ["Fixnum", "Float"].include?(x.class.name)}
    total%1==0 ? total.to_i : total
  end
end

a = [1, 2, 3, "y"]
b = [2, "z", 4.3]

puts a.sum #=> 6
puts b.sum #=> 6.3