Hi all, In Rails console (just doing a general exercise in ruby design patterns), I create two classes: ruby-1.9.2-p136 :023 > class A ruby-1.9.2-p136 :024?> attr_accessor :name, :balance ruby-1.9.2-p136 :025?> def initialize(name, balance) ruby-1.9.2-p136 :026?> @name = name ruby-1.9.2-p136 :027?> @balance = balance ruby-1.9.2-p136 :028?> end ruby-1.9.2-p136 :029?> def <=>(other) ruby-1.9.2-p136 :030?> balance <=> other.balance ruby-1.9.2-p136 :031?> end ruby-1.9.2-p136 :032?> end => nil ruby-1.9.2-p136 :033 > class Portfolio ruby-1.9.2-p136 :034?> include Enumerable ruby-1.9.2-p136 :035?> def initialize ruby-1.9.2-p136 :036?> @accounts = [] ruby-1.9.2-p136 :037?> end ruby-1.9.2-p136 :038?> def each(&block) ruby-1.9.2-p136 :039?> @accounts.each(&block) ruby-1.9.2-p136 :040?> end ruby-1.9.2-p136 :041?> def add_account(account) ruby-1.9.2-p136 :042?> @accounts << account ruby-1.9.2-p136 :043?> end ruby-1.9.2-p136 :044?> end => nil client code: ruby-1.9.2-p136 :045 > portfolio = Portfolio.new => #<Portfolio:0x00000105d47118 @accounts=[]> ruby-1.9.2-p136 :091 > a = A.new(''n'',1000) => #<A:0x00000105fdc478 @name="n", @balance=1000> ruby-1.9.2-p136 :092 > portfolio.add_account(a) => [#<A:0x00000105fdc478 @name="n", @balance=1000>] ruby-1.9.2-p136 :093 > b = A.new(''b'',2000) => #<A:0x00000105fd0ba0 @name="b", @balance=2000> ruby-1.9.2-p136 :094 > portfolio.add_account(b) => [#<A:0x00000105fdc478 @name="n", @balance=1000>, #<A: 0x00000105fd0ba0 @name="b", @balance=2000>] ruby-1.9.2-p136 :095 > portfolio.each {|n, b| n <=> b } NoMethodError: undefined method `balance'' for nil:NilClass It appears that the each iterator does not support passing in two arguments? because I expect n to be object 0x00000105fdc478 and I expect b to be object 0x00000105fd0ba0. Then I expect once the each iterator of portfolio is called and executed, we in turn call each on the array of accounts, passing in our block. When that call occurs, we invoke the defined <=> instance method of A class, passing in the two objects stored in @accounts. This in turn will call the <=> method of enumerable and perform comparison operation. However, what I just described above does not occur. thanks for response -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
John Merlino wrote in post #1029066:> client code: > ruby-1.9.2-p136 :095 > portfolio.each {|n, b| n <=> b }You obviously aren''t quite understanding what block actually are.> NoMethodError: undefined method `balance'' for nil:NilClassWell yea. The block that gets passed into each was designed to take one argument. Each is a block (a.k.a closure, a.k.a lambda function, a.k.a anonymous function) that has a design similar to any regular method or function, for example: def each(arg) do # method body end If you were to pass two arguments to that method you''d have a similar result: self.each(a, b) => Results in something just as nasty. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Sat, Oct 29, 2011 at 00:09, John Merlino <stoicism1-YDxpq3io04c@public.gmane.org> wrote:> ruby-1.9.2-p136 :095 > portfolio.each {|n, b| n <=> b } > NoMethodError: undefined method `balance'' for nil:NilClass > > It appears that the each iterator does not support passing in two > arguments?Correct. "each" means "apply this block to each of this collection''s elements in turn", not "... in parallel". Otherwise you''d have to have the block accept exactly as many args as there are elements. (Or of course accept a collection, in which case you''re back to square one.) -Dave -- LOOKING FOR WORK! What: Ruby (on/off Rails), Python, other modern languages. Where: Northern Virginia, Washington DC (near Orange Line), and remote work. See: davearonson.com (main) * codosaur.us (code) * dare2xl.com (excellence). Specialization is for insects. (Heinlein) - Have Pun, Will Babble! (Aronson) -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
thanks for responses, it makes sense that it failed, because the each iterator is only intended to iterate over one object at a time. I need more time of my own to investigate a better way to do this. On Oct 29, 2:28 pm, Dave Aronson <googlegroups2d...-BRiZGj7G2yRXqviUI+FSNg@public.gmane.org> wrote:> On Sat, Oct 29, 2011 at 00:09, John Merlino <stoici...-YDxpq3io04c@public.gmane.org> wrote: > > ruby-1.9.2-p136 :095 > portfolio.each {|n, b| n <=> b } > > NoMethodError: undefined method `balance'' for nil:NilClass > > > It appears that the each iterator does not support passing in two > > arguments? > > Correct. "each" means "apply this block to each of this collection''s > elements in turn", not "... in parallel". Otherwise you''d have to > have the block accept exactly as many args as there are elements. (Or > of course accept a collection, in which case you''re back to square > one.) > > -Dave > > -- > LOOKING FOR WORK! What: Ruby (on/off Rails), Python, other modern languages. > Where: Northern Virginia, Washington DC (near Orange Line), and remote work. > See: davearonson.com (main) * codosaur.us (code) * dare2xl.com (excellence). > Specialization is for insects. (Heinlein) - Have Pun, Will Babble! (Aronson)-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Sun, Oct 30, 2011 at 21:09, John Merlino <stoicism1-YDxpq3io04c@public.gmane.org> wrote:> I need more time of my own to investigate a better way to do this.Maybe we can still help. What were you trying to accomplish with the code that failed: portfolio.each {|n, b| n <=> b } ? Were you trying to sort them? Maybe you could just delegate that to accounts. -Dave -- LOOKING FOR WORK! What: Ruby (on/off Rails), Python, other modern languages. Where: Northern Virginia, Washington DC (near Orange Line), and remote work. See: davearonson.com (main) * codosaur.us (code) * dare2xl.com (excellence). Specialization is for insects. (Heinlein) - Have Pun, Will Babble! (Aronson) -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.