I have the code which creates the following made up of an array of 3 TreatLists each with a number of Treatlistitems (I''ve broken it up to make it easier to read). ?> @breakdown => [ #<Treatlist:0x23b98ac @items=[ #<Treatlistitem:0x2389ef4 @longname="Eye Brow Shape", @spend=17.0, @prodtreat="T", @numsold=2, @unitcost=10.0>]>, #<Treatlist:0x235df34 @items=[#<Treatlistitem:0x235b16c @longname="Back Massage", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x23597cc @longname="Hopi Ear Candles", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x23582dc @longname="Back Massage (Essential Oils)", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>]>, #<Treatlist:0x2357a1c @items=[ #<Treatlistitem:0x2351b30 @longname="Back Massage", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x234f9fc @longname="Hopi Ear Candles", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x234cf90 @longname="Eye Brow Shape", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x2349db8 @longname="Full Leg Wax DSS", @spend=18.0, @prodtreat="T", @numsold=2, @unitcost=10.0>, #<Treatlistitem:0x23476bc @longname="Bridal Make Up", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x2342fcc @longname="Collin Face Powder", @spend=10.0, @prodtreat="P", @numsold=1, @unitcost=10.0>]>] I''m trying to add together the ''spend'' figures from each but only if prodtreat = T or P. When I try the following:>> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "T"}=> 30.0 it works!!! But when I try it with P ...>> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "P"}I get the following: NoMethodError: You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.+ from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `sum'' from (irb):65:in `inject'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `each'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `inject'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `sum'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:61:in `sum'' from (irb):65>>I really have no idea why this is not working or not returning a zero value?! Any ideas please? Cheers Darren
I have also noted that with @breakdown[2] it doesn''t work even though I know I have a "P" in there!>> @breakdown[2]=> #<Treatlist:0x2357a1c @items=[ #<Treatlistitem:0x2351b30 @longname="Back Massage", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x234f9fc @longname="Hopi Ear Candles", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x234cf90 @longname="Eye Brow Shape", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x2349db8 @longname="Full Leg Wax DSS", @spend=18.0, @prodtreat="T", @numsold=2, @unitcost=10.0>, #<Treatlistitem:0x23476bc @longname="Bridal Make Up", @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, #<Treatlistitem:0x2342fcc @longname="Collin Face Powder", @spend=10.0, @prodtreat="P", @numsold=1, @unitcost=10.0>]>>> @breakdown[2].items.sum{|item| item.spend if item.prodtreat == "P"}NoMethodError: You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.+ from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `sum'' from (irb):68:in `inject'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `each'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `inject'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:63:in `sum'' from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ active_support/core_ext/enumerable.rb:61:in `sum'' from (irb):68 This is confusing me mightily!
Looks like the following works: @breakdown[2].items.find_all {|item| item.prodtreat == "T"}.sum{|item| item.spend} Really have no idea why? So any help would be enlightening. Thanks Darren PS. Have a feeling that this can be simplified to: @breakdown[2].items.find_all {|item| item.prodtreat == "T"}.sum (&:spend)
2009/8/26 Ruby on Rails: Talk <dazzaroonie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > I have the code which creates the following made up of an array of 3 > TreatLists each with a number of Treatlistitems (I''ve broken it up to > make it easier to read). > > ?> @breakdown > => [ > #<Treatlist:0x23b98ac @items=[ > #<Treatlistitem:0x2389ef4 @longname="Eye Brow Shape", @spend=17.0, > @prodtreat="T", @numsold=2, @unitcost=10.0>]>, > > #<Treatlist:0x235df34 > @items=[#<Treatlistitem:0x235b16c @longname="Back Massage", > @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x23597cc @longname="Hopi Ear Candles", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x23582dc @longname="Back Massage (Essential Oils)", > @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>]>, > > #<Treatlist:0x2357a1c @items=[ > #<Treatlistitem:0x2351b30 @longname="Back Massage", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x234f9fc @longname="Hopi Ear Candles", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x234cf90 @longname="Eye Brow Shape", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x2349db8 @longname="Full Leg Wax DSS", @spend=18.0, > @prodtreat="T", @numsold=2, @unitcost=10.0>, > #<Treatlistitem:0x23476bc @longname="Bridal Make Up", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x2342fcc @longname="Collin Face Powder", @spend=10.0, > @prodtreat="P", @numsold=1, @unitcost=10.0>]>] > > I''m trying to add together the ''spend'' figures from each but only if > prodtreat = T or P. When I try the following: > >>> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "T"} > => 30.0 > > it works!!! > > But when I try it with P ... > >>> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "P"} > > I get the following: > > NoMethodError: You have a nil object when you didn''t expect it! > You might have expected an instance of Array. > The error occurred while evaluating nil.+ > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `sum'' > from (irb):65:in `inject'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `each'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `inject'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `sum'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:61:in `sum'' > from (irb):65 >>> > > I really have no idea why this is not working or not returning a zero > value?! Any ideas please?A bit of a guess here but it may be that fact that this will attempt to include some nil values in the sum as the result of the block will be nil (I think) for values that do not match. Perhaps this is ok if the first record is included in the sum but later ones not (so it is performing value + nil) but fails if the first one is not included in the sum (so it performs nil + value). Just a guess. Colin
On Aug 27, 8:03 am, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> 2009/8/26 Ruby on Rails: Talk <dazzaroo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>: > > > I really have no idea why this is not working or not returning a zero > > value?! Any ideas please? > > A bit of a guess here but it may be that fact that this will attempt > to include some nil values in the sum as the result of the block will > be nil (I think) for values that do not match. Perhaps this is ok if > the first record is included in the sum but later ones not (so it is > performing value + nil) but fails if the first one is not included in > the sum (so it performs nil + value). Just a guess. >That is indeed it - the value of an if statement where the condition is not met. One way of solving this would be to change the code to if ... item.spend else 0 end Fred
Hi, I have pasted a simplified version of the problem you are trying to understand. You cannot do a ''sum'' on a collection that has a ''nil'' as one of its elements. If ''nil'' happens to be the first element, you will get the ''NoMethodError'' , as the method ''+'' is called on it (as shown in the error trace ''nil.+'') . Also note that the elements of the collection have to define the method ''+'' for sum to work. ''sum'' works by using ''inject'' which in turn takes the first element (unless an initial value is provided) and calls + on it using the next element in collection as the input, then takes the result and repeats the process for all the rest of the elements>> ar = [1,2,3]=> [1, 2, 3]>> ar.sum=> 6>> ar = [nil,2,3]=> [nil, 2, 3]>> ar.sumNoMethodError: You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.+ from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.3/lib/ active_support/core_ext/enumerable.rb:63:in `sum'' from (irb):16:in `inject'' ...>>regards, mvp On Aug 26, 10:00 pm, "Ruby on Rails: Talk" <dazzaroo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I have the code which creates the following made up of an array of 3 > TreatLists each with a number of Treatlistitems (I''ve broken it up to > make it easier to read). > > ?> @breakdown > => [ > #<Treatlist:0x23b98ac @items=[ > #<Treatlistitem:0x2389ef4 @longname="Eye Brow Shape", @spend=17.0, > @prodtreat="T", @numsold=2, @unitcost=10.0>]>, > > #<Treatlist:0x235df34 > @items=[#<Treatlistitem:0x235b16c @longname="Back Massage", > @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x23597cc @longname="Hopi Ear Candles", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x23582dc @longname="Back Massage (Essential Oils)", > @spend=10.0, @prodtreat="T", @numsold=1, @unitcost=10.0>]>, > > #<Treatlist:0x2357a1c @items=[ > #<Treatlistitem:0x2351b30 @longname="Back Massage", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x234f9fc @longname="Hopi Ear Candles", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x234cf90 @longname="Eye Brow Shape", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x2349db8 @longname="Full Leg Wax DSS", @spend=18.0, > @prodtreat="T", @numsold=2, @unitcost=10.0>, > #<Treatlistitem:0x23476bc @longname="Bridal Make Up", @spend=10.0, > @prodtreat="T", @numsold=1, @unitcost=10.0>, > #<Treatlistitem:0x2342fcc @longname="Collin Face Powder", @spend=10.0, > @prodtreat="P", @numsold=1, @unitcost=10.0>]>] > > I''m trying to add together the ''spend'' figures from each but only if > prodtreat = T or P. When I try the following: > > >> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "T"} > > => 30.0 > > it works!!! > > But when I try it with P ... > > >> @breakdown[1].items.sum{|item| item.spend if item.prodtreat == "P"} > > I get the following: > > NoMethodError: You have a nil object when you didn''t expect it! > You might have expected an instance of Array. > The error occurred while evaluating nil.+ > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `sum'' > from (irb):65:in `inject'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `each'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `inject'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:63:in `sum'' > from /Library/Ruby/Gems/1.8/gems/activesupport-2.2.2/lib/ > active_support/core_ext/enumerable.rb:61:in `sum'' > from (irb):65 > > > > I really have no idea why this is not working or not returning a zero > value?! Any ideas please? > > Cheers > > Darren