Question on the Ruby Programming Language Book

Discussion in 'Ruby' started by Bharat Ruparel, Mar 3, 2008.

  1. I have been reading The Ruby Programming Language book by David Flanagan
    and Matz. It is written quite well. Some examples are not clear (to
    me): Here is one from Chapter 7 page 244 which defines a class to set
    enumerated types:

    class Season
    NAMES = %w{ Spring Summer Autumn Winter } # Array of season names
    INSTANCES = [] # Array of Season objects

    def initialize(n) # The state of a season is just its
    @n = n # index in the NAMES and INSTANCES arrays
    end

    def to_s # Return the name of a season
    NAMES[@n]
    end

    # This code creates instances of this class to represent the seasons
    # and defines constants to refer to those instances.
    # Note that we must do this after initialize is defined.
    NAMES.each_with_index do |name,index|
    instance = new(index) # Create a new instance
    INSTANCES[index] = instance # Save it in an array of instances
    const_set name, instance # Define a constant to refer to it
    end

    # Now that we have created all the instances we'll ever need, we must
    # prevent any other instances from being created
    private_class_method :new,:allocate # Make the factory methods
    private
    private :dup, :clone # Make copying methods private
    end

    My question is how do you use this class from the client code? Can
    someone give some examples?

    Thanks.

    Bharat
    --
    Posted via http://www.ruby-forum.com/.
    Bharat Ruparel, Mar 3, 2008
    #1
    1. Advertising

  2. Bharat Ruparel

    Bill Kelly Guest

    From: "Bharat Ruparel" <>
    >
    > My question is how do you use this class from the client code? Can
    > someone give some examples?


    spring = Season::Spring
    summer = Season::Summer

    etc.


    Regards,

    Bill
    Bill Kelly, Mar 3, 2008
    #2
    1. Advertising

  3. Hello Bill,
    Thanks for your quick response. You gave me the following example.
    > spring = Season::Spring
    > summer = Season::Summer

    I typed this into my NetBeans IDE and it indeed shows that both spring
    and summer are valid object. My follow-up questions are more to learn
    than to question the validity of your answer since I am trying to
    understand this:

    1 Why do you have to create enumerated objects this way? This seems a
    long way off from Ruby's philosophy of being succint. Just to define a
    few "object" constants I have to go through this?

    2. In the code block below:

    NAMES.each_with_index do |name,index|
    instance = new(index) # Create a new instance
    INSTANCES[index] = instance # Save it in an array of instances
    const_set name, instance # Define a constant to refer to it
    end

    The block is apparently setting the "name" to the "instance". What does
    this buy us from a programming point of view?

    Bharat
    --
    Posted via http://www.ruby-forum.com/.
    Bharat Ruparel, Mar 3, 2008
    #3
  4. Bharat Ruparel

    Avdi Grimm Guest

    On Mon, Mar 3, 2008 at 5:44 PM, Bharat Ruparel <> wrote:
    > 1 Why do you have to create enumerated objects this way? This seems a
    > long way off from Ruby's philosophy of being succint. Just to define a
    > few "object" constants I have to go through this?


    In general, Ruby programmers don't create enumerated objects. There's
    rarely a need for them. The solution you demonstrated above is looks
    like an example of how one might go about it if one really wanted to
    emulate C++-style enumerations. Generally you would just use symbols,
    though.

    > The block is apparently setting the "name" to the "instance". What does
    > this buy us from a programming point of view?


    That's the part that actually creates those constants Season::Summer,
    Season::Autumn, etc. Without it they would not exist.

    --
    Avdi
    Avdi Grimm, Mar 3, 2008
    #4
  5. Bharat Ruparel

    7stud -- Guest

    Bharat Ruparel wrote:
    > I have been reading The Ruby Programming Language book by David Flanagan
    > and Matz. It is written quite well. Some examples are not clear (to
    > me):


    I looked at the book in the bookstore. I was very disappointed. I read
    the first chapter, and it is way too technical for me. It is nothing
    like the author's Javascript book, which is very easy to read, yet is
    still the definitive book on the subject. I was surprised at how thin
    the book was. I wish the author had fleshed things out a little more
    and made the book easier to read.

    The prologue does say that it is not a beginner's book.


    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Mar 3, 2008
    #5
  6. > In general, Ruby programmers don't create enumerated objects. There's
    > rarely a need for them. The solution you demonstrated above is looks
    > like an example of how one might go about it if one really wanted to
    > emulate C++-style enumerations. Generally you would just use symbols,
    > though.


    Thank you. On one hand, I have a high regard for David Flanagan and
    Matz. On the other hand, I must admit that I am a bit disappointed with
    their selection of examples though. "Technicallly," the book is mostly
    quite correct, you just have to stretch your brain-cells a bit for more
    realistic applications. C++ was a long time ago, but thanks for the
    reminder, it does look a bit like the past coming back to haunt me.

    Regards,

    Bharat
    --
    Posted via http://www.ruby-forum.com/.
    Bharat Ruparel, Mar 3, 2008
    #6
  7. Bharat Ruparel

    James Britt Guest

    Bharat Ruparel wrote:

    > 1 Why do you have to create enumerated objects this way? This seems a
    > long way off from Ruby's philosophy of being succint. Just to define a
    > few "object" constants I have to go through this?
    >


    Well, you can add this method:


    def next
    INSTANCES[ (@n+1) % 4]
    end


    and then do this:


    season = Season::Autumn
    puts season
    puts season.next
    puts season.next.next



    --
    James Britt

    "The greatest obstacle to discovery is not ignorance, but the illusion
    of knowledge."
    - D. Boorstin
    James Britt, Mar 3, 2008
    #7
  8. > season = Season::Autumn
    > puts season
    > puts season.next
    > puts season.next.next


    Thanks Jim. That is cool! No, way cool!!
    --
    Posted via http://www.ruby-forum.com/.
    Bharat Ruparel, Mar 4, 2008
    #8
  9. On Mon, Mar 3, 2008 at 3:44 PM, James Britt <> wrote:
    > Bharat Ruparel wrote:
    >
    > > 1 Why do you have to create enumerated objects this way? This seems a
    > > long way off from Ruby's philosophy of being succint. Just to define a
    > > few "object" constants I have to go through this?
    > >

    >
    > Well, you can add this method:
    >
    >
    > def next
    > INSTANCES[ (@n+1) % 4]
    > end
    >
    >
    > and then do this:
    >
    >
    > season = Season::Autumn
    > puts season
    > puts season.next
    > puts season.next.next
    >



    Or, better (in Ruby 1.9) add this instead:
    ---
    class Season

    extend Enumerable

    def self.each
    NAMES.each {|name| yield const_get(name.to_s)}
    self
    end

    # more direct than making it sortable by defining a <=> operator,
    # though you could do that instead.
    def self.sort(&block)
    if block then to_a.sort(&block) else to_a end
    end

    end
    ---
    And then try (not really all that useful for seasons, but shows that
    you've got the full power of Enumerable at hand):
    ---
    Season.sort {|s1, s2| s1.to_s <=> s2.to_s}.each {|s| puts s.to_s}
    Season.sort_by {|season| season.to_s}.each {|s| puts s.to_s}
    Season.map {|season| season.to_s}.each {|s| puts s}
    ---
    And finally (the one I like the most):
    ---
    seasons = Season.cycle
    puts seasons.next
    puts seasons.next
    puts seasons.next
    Christopher Dicely, Mar 4, 2008
    #9
  10. And, no, I can't explain why I used this:
    --
    NAMES.each {|name| yield const_get(name.to_s)}
    --

    Instead of:
    ---
    INSTANCES.each {|season| yield season}
    --

    Just trying to make things too complex, I guess.

    On Mon, Mar 3, 2008 at 6:28 PM, Christopher Dicely <> wrote:
    > On Mon, Mar 3, 2008 at 3:44 PM, James Britt <> wrote:
    > > Bharat Ruparel wrote:
    > >
    > > > 1 Why do you have to create enumerated objects this way? This seems a
    > > > long way off from Ruby's philosophy of being succint. Just to define a
    > > > few "object" constants I have to go through this?
    > > >

    > >
    > > Well, you can add this method:
    > >
    > >
    > > def next
    > > INSTANCES[ (@n+1) % 4]
    > > end
    > >
    > >
    > > and then do this:
    > >
    > >
    > > season = Season::Autumn
    > > puts season
    > > puts season.next
    > > puts season.next.next
    > >

    >
    >
    > Or, better (in Ruby 1.9) add this instead:
    > ---
    > class Season
    >
    > extend Enumerable
    >
    > def self.each
    > NAMES.each {|name| yield const_get(name.to_s)}
    > self
    > end
    >
    > # more direct than making it sortable by defining a <=> operator,
    > # though you could do that instead.
    > def self.sort(&block)
    > if block then to_a.sort(&block) else to_a end
    > end
    >
    > end
    > ---
    > And then try (not really all that useful for seasons, but shows that
    > you've got the full power of Enumerable at hand):
    > ---
    > Season.sort {|s1, s2| s1.to_s <=> s2.to_s}.each {|s| puts s.to_s}
    > Season.sort_by {|season| season.to_s}.each {|s| puts s.to_s}
    > Season.map {|season| season.to_s}.each {|s| puts s}
    > ---
    > And finally (the one I like the most):
    > ---
    > seasons = Season.cycle
    > puts seasons.next
    > puts seasons.next
    > puts seasons.next
    > .
    > .
    > .
    > ---
    > (You can do the same thing to make the class Season an
    > Enumerable in Ruby 1.8, but Ruby 1.9's Enumerators
    > and the Enumerable#cycle method really make this
    > cool, IMO.)
    >
    Christopher Dicely, Mar 4, 2008
    #10
  11. Bharat Ruparel

    James Britt Guest

    Bharat Ruparel wrote:
    >> season = Season::Autumn
    >> puts season
    >> puts season.next
    >> puts season.next.next

    >
    > Thanks Jim. That is cool! No, way cool!!


    Thanks.

    The main point is that, if you just want cheap, reliable constant
    things, symbols are handy (e.g. :winter, :summer will work as fixed
    values), but if you have a set of constants for which you want some
    associated behavior, then a class makes sense.



    --
    James Britt

    Liberty means responsibility. That is why most men dread it.
    - George Bernard Shaw
    James Britt, Mar 4, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Harry Meier
    Replies:
    16
    Views:
    652
    Andrew Koenig
    Sep 8, 2003
  2. Replies:
    3
    Views:
    478
    Puppet_Sock
    Jun 21, 2006
  3. Mike
    Replies:
    1
    Views:
    302
    F.J.K.
    Sep 20, 2006
  4. Akira Kitada
    Replies:
    1
    Views:
    848
    Paul Rubin
    Feb 12, 2009
  5. ashu

    About C programming language book K&R

    ashu, May 4, 2012, in forum: C Programming
    Replies:
    7
    Views:
    887
    TonyMc
    May 8, 2012
Loading...

Share This Page