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@googlegroups.com.
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.

Search Discussions

  • Robert Walker at Oct 29, 2011 at 4:35 am

    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:NilClass
    Well 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@googlegroups.com.
    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.
  • Dave Aronson at Oct 29, 2011 at 6:29 pm

    On Sat, Oct 29, 2011 at 00:09, John Merlino 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@googlegroups.com.
    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.
  • John Merlino at Oct 31, 2011 at 1:09 am
    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 wrote:
    On Sat, Oct 29, 2011 at 00:09, John Merlino 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@googlegroups.com.
    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.
  • Dave Aronson at Oct 31, 2011 at 2:08 pm

    On Sun, Oct 30, 2011 at 21:09, John Merlino 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@googlegroups.com.
    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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprubyonrails-talk @
categoriesrubyonrails
postedOct 29, '11 at 4:17a
activeOct 31, '11 at 2:08p
posts5
users3
websiterubyonrails.org
irc#RubyOnRails

People

Translate

site design / logo © 2022 Grokbase