Why can I here sum numbers

Hello,

I have a method that takes a unlimited number of integers and adds

them all together .

So I did this :
   def sum (*numbers)
numbers.each do |n| sum += n if n.is_a? Integer
end
end
but when I run it I see this error message : `block in sum': undefined method `+' for nil:NilClass (NoMethodError)
from `each'
from `sum'
from `

  why do I get a nilClass there. As far as I know this is a normal

way to add things up.

  Roelof

The 'sum' variable needs to be initialized or else it takes the value of
nil. So in the line 'sum += n', sum is nil. You can solve this by setting
sum = 0 at the beginning of the method.

···

On Wed, Nov 19, 2014 at 11:22 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

I have a method that takes a unlimited number of integers and adds them
all together .

So I did this :

def sum (*numbers)
   numbers.each do |n|
      sum += n if n.is_a? Integer
   end
end

but when I run it I see this error message :

`block in sum': undefined method `+' for nil:NilClass (NoMethodError)
  from `each'
  from `sum'
  from `

'
why do I get a nilClass there. As far as I know this is a normal way to
add things up.

Roelof

Thanks,

  That is solved,

  But now I have this test :

  Test.assert_equals(6, sum (1,2,3) )

  And I see this error :

  -e:10: syntax error, unexpected ( arg, expecting keyword_do or '{'

or ‘(’
Test.assert_equals(6, sum (1,2,3) )

  Roelof

  Jeremy Axelrod schreef op 20-11-2014 8:31:
    The 'sum' variable needs to be initialized or else

it takes the value of nil. So in the line ‘sum += n’, sum is
nil. You can solve this by setting sum = 0 at the beginning of
the method.

Hello,

          I have a method that takes a unlimited number of integers

and adds them all together .

          So I did this :
> >    def sum (*numbers)
> > numbers.each do |n| sum += n if n.is_a? Integer
> > end
> > end
> > but when I run it I see this error message : `block in sum': undefined method `+' for nil:NilClass (NoMethodError)
> > from `each'
> > from `sum'
> > from `
···
      On Wed, Nov 19, 2014 at 11:22 PM, > Roelof Wobben <r.wobben@home.nl> >           wrote:

          why do I get a nilClass there. As far as I know this is a

normal way to add things up.

              Roelof

Yup, you need sum to be defined. Use inject to do just that

···

On Thu, Nov 20, 2014 at 9:31 AM, Jeremy Axelrod <axelrod.jeremy@gmail.com> wrote:

The 'sum' variable needs to be initialized or else it takes the value of
nil. So in the line 'sum += n', sum is nil. You can solve this by setting
sum = 0 at the beginning of the method.

On Wed, Nov 19, 2014 at 11:22 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

I have a method that takes a unlimited number of integers and adds them
all together .

So I did this :

def sum (*numbers)
   numbers.each do |n|
      sum += n if n.is_a? Integer
   end
end

but when I run it I see this error message :

`block in sum': undefined method `+' for nil:NilClass (NoMethodError)
  from `each'
  from `sum'
  from `

'
why do I get a nilClass there. As far as I know this is a normal way to
add things up.

Roelof

--
--
*Augusts Bautra*

*Creative MobileKronvalda bulvaris 10, Riga**office: 00371 67227747*
*mobile: 00371 29957771*
*www.creo.mobi <http://www.creo.mobi/&gt;\*

I would recommend the "inject" approach here. The reason why you are
getting nilClass and the error "undefined method `+' for nil:NilClass" is
because in the block, you are trying to call the "+" method on the "sum"
object which is essentially nil. A way to avoid this error is by defining a
variable "sum" outside the block and setting it to 0.

···

On Thu, Nov 20, 2014 at 1:01 PM, Jeremy Axelrod <axelrod.jeremy@gmail.com> wrote:

The 'sum' variable needs to be initialized or else it takes the value of
nil. So in the line 'sum += n', sum is nil. You can solve this by setting
sum = 0 at the beginning of the method.

On Wed, Nov 19, 2014 at 11:22 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

I have a method that takes a unlimited number of integers and adds them
all together .

So I did this :

def sum (*numbers)
   numbers.each do |n|
      sum += n if n.is_a? Integer
   end
end

but when I run it I see this error message :

`block in sum': undefined method `+' for nil:NilClass (NoMethodError)
  from `each'
  from `sum'
  from `

'
why do I get a nilClass there. As far as I know this is a normal way to
add things up.

Roelof

--
Regards
Vineeth B S

Accidental submit..

As I started.. use Inject

def sum (*numbers)
   numbers.inject {|sum, n| sum + n }
end

Inject initialises an empty (zero) receptacle for aggregated data for you.

More at Jay Fields' Thoughts: Ruby: inject

···

On Thu, Nov 20, 2014 at 9:38 AM, Roelof Wobben <r.wobben@home.nl> wrote:

Thanks,

That is solved,
But now I have this test :

Test.assert_equals(6, sum (1,2,3) )

And I see this error :

-e:10: syntax error, unexpected ( arg, expecting keyword_do or '{' or '('
Test.assert_equals(6, sum (1,2,3) )

Roelof

Jeremy Axelrod schreef op 20-11-2014 8:31:

The 'sum' variable needs to be initialized or else it takes the value of
nil. So in the line 'sum += n', sum is nil. You can solve this by setting
sum = 0 at the beginning of the method.

On Wed, Nov 19, 2014 at 11:22 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

I have a method that takes a unlimited number of integers and adds them
all together .

So I did this :

def sum (*numbers)
   numbers.each do |n|
      sum += n if n.is_a? Integer
   end
end

but when I run it I see this error message :

`block in sum': undefined method `+' for nil:NilClass (NoMethodError)
  from `each'
  from `sum'
  from `

'
why do I get a nilClass there. As far as I know this is a normal way to
add things up.

Roelof

--
--
*Augusts Bautra*

*Creative MobileKronvalda bulvaris 10, Riga**office: 00371 67227747*
*mobile: 00371 29957771*
*www.creo.mobi <http://www.creo.mobi/&gt;\*

What if you put a number in the array?

···

Sent from my phone

On Nov 20, 2014, at 12:09 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Thu, Nov 20, 2014 at 8:41 AM, Augusts Bautra <augusts@creo.mobi> wrote:

As I started.. use Inject

def sum (*numbers)
  numbers.inject {|sum, n| sum + n }
end

Inject initialises an empty (zero) receptacle for aggregated data for you.

No. Your approach is broken because

irb(main):001:0> .inject {|sum, n| sum + n }
=> nil

More at Jay Fields' Thoughts: Ruby: inject

That has it correct in the first example. You need to pass in the
neutral element of the operation:

irb(main):002:0> .inject(0) {|sum, n| sum + n }
=> 0

Cheers

robert

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

As I started.. use Inject

def sum (*numbers)
   numbers.inject {|sum, n| sum + n }
end

Inject initialises an empty (zero) receptacle for aggregated data for you.

No. Your approach is broken because

irb(main):001:0> .inject {|sum, n| sum + n }
=> nil

More at http://blog.jayfields.com/2008/03/ruby-inject.html

That has it correct in the first example. You need to pass in the
neutral element of the operation:

irb(main):002:0> .inject(0) {|sum, n| sum + n }
=> 0

Cheers

robert

···

On Thu, Nov 20, 2014 at 8:41 AM, Augusts Bautra <augusts@creo.mobi> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

In the method you cannot know whether there are numbers in the
Enumerable passed to the method.

Kind regards

robert

···

On Thu, Nov 20, 2014 at 9:23 AM, Jeremy Axelrod <axelrod.jeremy@gmail.com> wrote:

What if you put a number in the array?

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Robert Klemme schreef op 20-11-2014 9:28:

···

On Thu, Nov 20, 2014 at 9:23 AM, Jeremy Axelrod > <axelrod.jeremy@gmail.com> wrote:

What if you put a number in the array?

In the method you cannot know whether there are numbers in the
Enumerable passed to the method.

Kind regards

robert

Can I have a answer to my question why the test is failing ??

Roelof

May be the space between sum and (1,2,3) is throwing error.
Try this
Test.assert_equals(6, sum(1,2,3) )

···

On Thu, Nov 20, 2014 at 4:30 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Robert Klemme schreef op 20-11-2014 9:28:

On Thu, Nov 20, 2014 at 9:23 AM, Jeremy Axelrod >> <axelrod.jeremy@gmail.com> wrote:

What if you put a number in the array?

In the method you cannot know whether there are numbers in the
Enumerable passed to the method.

Kind regards

robert

Can I have a answer to my question why the test is failing ??

Roelof

--
Thanks,
Ramkumar M K,
Application Developer & Partner,
Mughil Technologies.

What is the result of "puts sum(1, 2, 3).inspect"?

If the result is "[1, 2, 3]", then you should return sum variable at
the end of sum method like below, but I recommend to use inject method.

def sum (*numbers)

  sum = 0

  numbers.each do |n|

    sum += n if n.is_a? Integer

  end

  sum

end

2014년 11월 20일 목요일, Roelof Wobben<r.wobben@home.nl>님이 작성한 메시지:

···

Robert Klemme schreef op 20-11-2014 9:28:

On Thu, Nov 20, 2014 at 9:23 AM, Jeremy Axelrod >> <axelrod.jeremy@gmail.com> wrote:

What if you put a number in the array?

In the method you cannot know whether there are numbers in the
Enumerable passed to the method.

Kind regards

robert

Can I have a answer to my question why the test is failing ??

Roelof

--
연세대학교 컴퓨터과학과 3학년 홍철주
010 6701 2676 | ang0123dev@gmail.com

naming is important
you have a function 'sum' with a variable 'sum'
the interpreter is calling the function where you expect it to use the
variable

···

On Thu, Nov 20, 2014 at 8:21 AM, Roelof Wobben <r.wobben@home.nl> wrote:

Robert Klemme schreef op 20-11-2014 10:21:

inject(0) {|s,x| s+x}

Thanks,

I tried the inject way like this :

def sum (*numbers)
   sum.inject(0) {|sum,nummer| sum + nummer}
end

with this test :

Test.assert_equals(6, sum(1,2,3) )

and now I see this error : -e:3: stack level too deep (SystemStackError)

Roelof

What is the result of "puts sum(1, 2, 3).inspect"?

What is the sound of one hand clapping. Sorry, your sentence just
triggered an association with me. :slight_smile:

If the result is "[1, 2, 3]", then you should return sum variable at the end
of sum method like below, but I recommend to use inject method.

def sum (*numbers)
  sum = 0
  numbers.each do |n|
    sum += n if n.is_a? Integer
  end
  sum
end

I would omit the test because coercing takes care of type conversions.
If at all, I'd use #to_int but not the type test.
See http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

So that would still give

def sum(*numbers)
  inject(0) {|s,x| s+x}
end

or

def sum(*numbers)
  inject(0) {|s,x| s+x.to_int}
end

Roelof, the space before (1,2,3) is the issue.

Kind regards

robert

···

On Thu, Nov 20, 2014 at 9:46 AM, 홍철주 <ang0123dev@gmail.com> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Robert Klemme schreef op 20-11-2014
10:21:

> inject(0) {|s,x| s+x}
Thanks,

I tried the inject way  like this :

def sum (*numbers)

   sum.inject(0) {|sum,nummer| sum + nummer}

end

with this test :

Test.assert_equals(6, sum(1,2,3) )

and now I see this error : -e:3: stack level too deep

(SystemStackError)

Roelof

Another valid option would be

def sum(*numbers)
  numbers.reduce(&:+)
end

···

On Thu, Nov 20, 2014 at 3:32 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Thu, Nov 20, 2014 at 4:09 PM, Roelof Wobben <r.wobben@home.nl> wrote:

> I had to do numbers.inject

Exactly.

> One other problem.
> The method schould reject everything which is not a integer.
> numbers.inject gives a error if you do sum (1,"a", 2)

Well, then it _does_ reject non numbers. Generally I probably would
not add a test to that method that simply skips non numbers. Let each
method do one thing properly. If you need filtering you can always do
the filtering before the call.

sum(*numbers.grep(Integer))

Btw, I would declare the interface of the method like this:

def sum(numbers)

i.e. use a single Enumerable. I think that is more flexible because
you can pass in an Enumerator which can be used to delegate the
filtering to the iteration (and not have to do it upfront and convert
to an Array like is needed with *numbers):

irb(main):004:0> def sum(n) n.inject(0){|s,x|s+x} end
=> nil
irb(main):005:0> sum([1,2,"foo"].to_enum(:grep, Integer))
=> 3

Kind regards

robert

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without
end}
http://blog.rubybestpractices.com/

--
George Drummond
Software Engineer

+44 (0)333 240 2222

[image: Rentify]
6-8 Long Lane, London EC1A 9HF
www.rentify.com

He is simply invoking #inject on the wrong object (i.e. result of
recursively invoking sum).

Cheers

robert

···

On Thu, Nov 20, 2014 at 3:26 PM, Chris Hulan <chris.hulan@gmail.com> wrote:

naming is important
you have a function 'sum' with a variable 'sum'
the interpreter is calling the function where you expect it to use the
variable

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Robert Klemme schreef op 20-11-2014 15:59:

···

On Thu, Nov 20, 2014 at 3:26 PM, Chris Hulan <chris.hulan@gmail.com> wrote:

naming is important
you have a function 'sum' with a variable 'sum'
the interpreter is calling the function where you expect it to use the
variable

He is simply invoking #inject on the wrong object (i.e. result of
recursively invoking sum).

Cheers

robert

Thanks,

I had to do numbers.inject

One other problem.
The method schould reject everything which is not a integer.
numbers.inject gives a error if you do sum (1,"a", 2)

Roelof

I had to do numbers.inject

Exactly.

One other problem.
The method schould reject everything which is not a integer.
numbers.inject gives a error if you do sum (1,"a", 2)

Well, then it _does_ reject non numbers. Generally I probably would
not add a test to that method that simply skips non numbers. Let each
method do one thing properly. If you need filtering you can always do
the filtering before the call.

sum(*numbers.grep(Integer))

Btw, I would declare the interface of the method like this:

def sum(numbers)

i.e. use a single Enumerable. I think that is more flexible because
you can pass in an Enumerator which can be used to delegate the
filtering to the iteration (and not have to do it upfront and convert
to an Array like is needed with *numbers):

irb(main):004:0> def sum(n) n.inject(0){|s,x|s+x} end
=> nil
irb(main):005:0> sum([1,2,"foo"].to_enum(:grep, Integer))
=> 3

Kind regards

robert

···

On Thu, Nov 20, 2014 at 4:09 PM, Roelof Wobben <r.wobben@home.nl> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Another valid option would be

def sum(*numbers)
  numbers.reduce(&:+)
end

$ ruby <<CODE

def sum(*numbers)
  numbers.reduce(&:+)
end
p sum()
CODE

nil

Same store: empty list is not properly dealt with.

Cheers

robert

···

On Thu, Nov 20, 2014 at 4:37 PM, George Drummond <drummond@rentify.com> wrote:

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/