[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Question on the Ruby Programming Language Book

Bharat Ruparel

3/3/2008 10:01:00 PM

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-....

10 Answers

Bill Kelly

3/3/2008 10:06:00 PM

0


From: "Bharat Ruparel" <bruparel@mercury.com>
>
> 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



Bharat Ruparel

3/3/2008 10:44:00 PM

0

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-....

Avdi Grimm

3/3/2008 10:56:00 PM

0

On Mon, Mar 3, 2008 at 5:44 PM, Bharat Ruparel <bruparel@mercury.com> 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

7stud --

3/3/2008 11:04:00 PM

0

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-....

Bharat Ruparel

3/3/2008 11:38:00 PM

0

> 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-....

James Britt

3/3/2008 11:44:00 PM

0

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

Bharat Ruparel

3/4/2008 12:03:00 AM

0

> 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-....

Christopher Dicely

3/4/2008 2:28:00 AM

0

On Mon, Mar 3, 2008 at 3:44 PM, James Britt <james.britt@gmail.com> 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

3/4/2008 2:33:00 AM

0

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 <cmdicely@gmail.com> wrote:
> On Mon, Mar 3, 2008 at 3:44 PM, James Britt <james.britt@gmail.com> 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.)
>

James Britt

3/4/2008 5:10:00 AM

0

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