Implanting a new method for a class

Hi there, I have a question regarding how to implant a new method into the
class Array. I would like to write a ruby file that sums all of the digits
in an array. I have tried this:

class Array
    def Array.sum
        until (Array.empty?)
            arraySum += Array.pop
        end
        puts arraySum
    end
end

Gave no error when I ran the code. My problem occur when i try to use this
method:

require "Library/Array_sum.rb"
a = [1..100]
a.sum

I get a NoMethodError on sum. Can anybody tell me what I did wrong here?
Thanks in advance :slight_smile:

You are confusing classes and instances of classes. You are defining
methods for the Array class, not for actual array instances.

  class A
    def A.foo
      puts "Class method of #{self.inspect}, instance of class #{self.class}"
    end
    def foo
      puts "Instance method for #{self.inspect}, of class #{self.class}"
    end
  end

  A.foo # prints "Class method of A, instance of class Class"
  a = A.new
  a.foo # prints "Instance method of <#A:0xb7ce9000> of class A"

You can implement sum like so:

  class Array
    def sum
      total = 0
      # self refers to the current array instance
      self.each { |elem| total += elem }
      total
    end

    # but you can also implement sum on the class Array itself. But then
    # you need to provide the array, that you want to know the sum of

···

On 2/12/06, Jeppe Jakobsen <jeppe88@gmail.com> wrote:

Hi there, I have a question regarding how to implant a new method into the
class Array. I would like to write a ruby file that sums all of the digits
in an array. I have tried this:

class Array
    def Array.sum
        until (Array.empty?)
            arraySum += Array.pop
        end
        puts arraySum
    end
end

Gave no error when I ran the code. My problem occur when i try to use this
method:

require "Library/Array_sum.rb"
a = [1..100]
a.sum

I get a NoMethodError on sum. Can anybody tell me what I did wrong here?
Thanks in advance :slight_smile:

    #
    def Array.sum arr
      arr.inject(0) { |total, elem| total += elem }
    end
  end

  puts [1,2,3,4].sum
  puts Array.sum([1,2,3,4,5])

be careful with "pop", it changes the Array!

  def sum!(arr)
    total = 0
    total += arr.pop until a.empty?
    total
  end

  arr = [5,4,3]
  p arr.sum! #=> 12
  p arr #=> arr is now empty!

-Levin

Jeppe Jakobsen wrote:

Hi there, I have a question regarding how to implant a new method into
the
class Array. I would like to write a ruby file that sums all of the
digits
in an array. I have tried this:

class Array
    def Array.sum
        until (Array.empty?)
            arraySum += Array.pop
        end
        puts arraySum
    end
end

Gave no error when I ran the code. My problem occur when i try to use
this
method:

require "Library/Array_sum.rb"
a = [1..100]
a.sum

I get a NoMethodError on sum. Can anybody tell me what I did wrong here?
Thanks in advance :slight_smile:

Jeppe,
You have a number of problems here. First, if what you are really trying
to do is to sum the array, rather than just learn how to add methods to
a class, then all you have to do is

a = [1,2,3]
a.inject { |v,n| v+n }
=> 6

Second, you created your function as a class method rather than an
instance method by calling it Array.sum. All you need is
def sum
...
end

This may be why you are getting the MethodNotFound, since the instance
of array "a" does not have this method - the class Array does.

Finally, a = [1..100] will give you an array with the first value being
the range [1..100], not an array with all the values from 1 to 100,
[1,2,3...].

Two suggestions: learn to use irb to see what happens when you call
methods, and (2) pick up Programming Ruby by Dave Thomas if you have not
already done so. It explains all of this in detail.

Hope this helps,
Keith

···

--
Posted via http://www.ruby-forum.com/\.

Jeppe Jakobsen wrote:

... I get a NoMethodError on sum. Can anybody tell me what I did wrong here?
Thanks in advance :slight_smile:

You've defined a class method (e.g. Array.sum)

You need to do this:

  class Array
      def sum
         until (Array.empty?)
  ...

···

--
James Britt

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - The Journal By & For Rubyists
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

Thank you, for sorting things out for me :slight_smile:

···

2006/2/12, Levin Alexander <levin@grundeis.net>:

On 2/12/06, Jeppe Jakobsen <jeppe88@gmail.com> wrote:
> Hi there, I have a question regarding how to implant a new method into
the
> class Array. I would like to write a ruby file that sums all of the
digits
> in an array. I have tried this:
>
> class Array
> def Array.sum
> until (Array.empty?)
> arraySum += Array.pop
> end
> puts arraySum
> end
> end
>
> Gave no error when I ran the code. My problem occur when i try to use
this
> method:
>
> require "Library/Array_sum.rb"
> a = [1..100]
> a.sum
>
> I get a NoMethodError on sum. Can anybody tell me what I did wrong here?
> Thanks in advance :slight_smile:

You are confusing classes and instances of classes. You are defining
methods for the Array class, not for actual array instances.

  class A
    def A.foo
      puts "Class method of #{self.inspect}, instance of class #{
self.class}"
    end
    def foo
      puts "Instance method for #{self.inspect}, of class #{self.class}"
    end
  end

  A.foo # prints "Class method of A, instance of class Class"
  a = A.new
  a.foo # prints "Instance method of <#A:0xb7ce9000> of class A"

You can implement sum like so:

  class Array
    def sum
      total = 0
      # self refers to the current array instance
      self.each { |elem| total += elem }
      total
    end

    # but you can also implement sum on the class Array itself. But then
    # you need to provide the array, that you want to know the sum of
    #
    def Array.sum arr
      arr.inject(0) { |total, elem| total += elem }
    end
  end

  puts [1,2,3,4].sum
  puts Array.sum([1,2,3,4,5])

be careful with "pop", it changes the Array!

  def sum!(arr)
    total = 0
    total += arr.pop until a.empty?
    total
  end

  arr = [5,4,3]
  p arr.sum! #=> 12
  p arr #=> arr is now empty!

-Levin

--
"winners never quit, quitters never win"