Alternate to case; generating a list of sub-classes

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

C:\code>
C:\code>
C:\code>type Driver.rb
require 'ArrayOfCreatures'

require 'Creature'
require 'AssistantViceTentacleAndOmbudsman'
require 'Dragon'
require 'DwarvenAngel'
require 'TeethDeer'

puts "\nquantity of creatures:"
numOfCreatures = gets.chomp.to_i

someCreatures = ArrayOfCreatures.new

0.upto(numOfCreatures) do |i|

        creatureType = Kernel.rand(4)

        case creatureType
        when 0
                someCreatures[i]=AssistantViceTentacleAndOmbudsman.new
        when 1
                someCreatures[i]=Dragon.new
        when 2
                someCreatures[i]=DwarvenAngel.new
        when 3
                someCreatures[i]=TeethDeer.new
        end
end

someCreatures.toString

C:\code>
C:\code>

thanks,

Thufir

Hi --

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

C:\code>
C:\code>type Driver.rb
require 'ArrayOfCreatures'

require 'Creature'
require 'AssistantViceTentacleAndOmbudsman'
require 'Dragon'
require 'DwarvenAngel'
require 'TeethDeer'

puts "\nquantity of creatures:"
numOfCreatures = gets.chomp.to_i

someCreatures = ArrayOfCreatures.new

0.upto(numOfCreatures) do |i|

       creatureType = Kernel.rand(4)

       case creatureType
       when 0
               someCreatures[i]=AssistantViceTentacleAndOmbudsman.new
       when 1
               someCreatures[i]=Dragon.new
       when 2
               someCreatures[i]=DwarvenAngel.new
       when 3
               someCreatures[i]=TeethDeer.new
       end
end

someCreatures.toString

Here's one possibility (untested):

   creatures = ArrayOfCreatures.new
   creature_classes = [AssistantViceTentacleAndOmbudsman, Dragon,
                       DwarvenAngel, TeethDeer]

   puts "\nquantity of creatures:"
   num_of_creatures = gets.to_i

   num_of_creatures.times do |i|
      creatures[i] = creature_classes[rand(4)].new
   end

David

···

On Thu, 8 Nov 2007, Thufir wrote:

--
Upcoming training by David A. Black/Ruby Power and Light, LLC:
   * Advancing With Rails, Edison, NJ, November 6-9
   * Advancing With Rails, Berlin, Germany, November 19-22
   * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
See http://www.rubypal.com for details!

Thufir wrote:

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically?

Perhaps:

class Creature
   @creature_classes =
   # hook to note when a class inherits
   def self.inherited(klass)
     @creature_classes << klass
   end

   # generate a random creature from among known subclasses
   def self.random_creature
     @creature_classes[ rand(@creature_classes.length) ].new
   end
end

hth
alex

cfp: ~> cat a.rb

class Creature
   Children =

   def self.inherited other
     super
   ensure
     Children << other
   end
end

Creature::List.sort_by{ rand }

a @ http://codeforpeople.com/

···

On Nov 7, 2007, at 4:57 PM, Thufir wrote:

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

I usually do this when I want to also recursively track subclasses:

module Hierarchy
  def inherited(cl)
    superclass.instance_eval { inherited cl }
    (@children ||= ) << cl
    cl.extend Hierarchy
  end

  attr_reader :children
end

class Foo
  extend Hierarchy
end

class Bar < Foo
end

class Dice < Bar
end

p Bar.children
p Foo.children

Cheers

robert

···

2007/11/8, Thufir <hawat.thufir@gmail.com>:

The below uses pseudo-random number generation to populate an array
with various monsters, all inherit from Creature. Can a list of
classes which inherit from Creature be generated automagically? There
must be a better technique to fill the array then the case
statement...

--
use.inject do |as, often| as.you_can - without end

[...]

Aha, I've been trying to figure out what a "hook" meant! :slight_smile:

thanks,

Thufir

···

On Nov 7, 4:15 pm, Alex Fenton <a...@deleteme.pressure.to> wrote:

Thufir wrote:
> The below uses pseudo-random number generation to populate an array
> with various monsters, all inherit from Creature. Can a list of
> classes which inherit from Creature be generated automagically?

Perhaps:

class Creature
   @creature_classes =
   # hook to note when a class inherits
   def self.inherited(klass)
     @creature_classes << klass
   end

cfp: ~> cat a.rb

class Creature
   Children =

[snip]

end

As an off-topic aside, I really like what you've done here. Normally I
do things like this:

class Foo
  @all =
  class << self
    attr_reader :all
  end
  def initialize
    self.class.all << self
  end
end

...but I've now seen the light how a constant scoped to the class can
make life far simpler.

class Foo
  ALL =
  def initialize
    ALL << self
  end
end

There's even some interesting benefits to the scoping, like:

# By inheriting the superclass's initialize,
# Bar1 instances get put into Foo::ALL
class Bar1 < Foo; end

# But I can totally branch on my own without worrying about
# any class variable sort of nonsense
class Bar2 < Foo
  ALL = # separate from Foo::ALL
  def initialize
    ALL << self
  end
end

Thanks for that, Ara!

···

On Nov 7, 5:16 pm, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

http://drawohara.tumblr.com/post/18708641

:wink:

a @ http://codeforpeople.com/

···

On Nov 8, 2007, at 6:08 AM, Robert Klemme wrote:

I usually do this when I want to also recursively track subclasses:

module Hierarchy
  def inherited(cl)
    superclass.instance_eval { inherited cl }
    (@children ||= ) << cl
    cl.extend Hierarchy
  end

  attr_reader :children
end

class Foo
  extend Hierarchy
end

class Bar < Foo
end

class Dice < Bar
end

p Bar.children
p Foo.children

Cheers

robert

--
use.inject do |as, often| as.you_can - without end

--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama

David A. Black wrote:

   creatures = ArrayOfCreatures.new
   [...]
   num_of_creatures.times do |i|
      creatures[i] = creature_classes[rand(4)].new
   end

Assuming that ArrayOfCreatures.new works like Array.new this can be simplified
to:
creatures = ArrayOfCreatures.new(num_of_creatures) do |i|
  creature_classes[rand(4)].new
end

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Phrogz wrote:

class Foo
  ALL =
  def initialize
    ALL << self
  end
end

There's even some interesting benefits to the scoping, like:

# By inheriting the superclass's initialize,
# Bar1 instances get put into Foo::ALL
class Bar1 < Foo; end

# But I can totally branch on my own without worrying about
# any class variable sort of nonsense
class Bar2 < Foo
  ALL = # separate from Foo::ALL
  def initialize
    ALL << self
  end
end

Thanks for that, Ara!

Careful though, constant scoping is not dynamic:

class Foo
   def self.show_all
     p ALL
   end
end

3.times {Foo.new}
Foo.show_all # [#<Foo:0x2ae5e8c>, #<Foo:0x2ae5e78>, #<Foo:0x2ae5e64>]

3.times {Bar2.new}
Bar2.show_all # [#<Foo:0x2ae5e8c>, #<Foo:0x2ae5e78>, #<Foo:0x2ae5e64>]

Of course, you can get dynamic scoping, it's just easy to forget:

class Foo
   def self.show_all
     p self::ALL
   end
end

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

On Nov 8, 10:13 am, Sebastian Hungerecker
[...]

Assuming that ArrayOfCreatures.new works like Array.new this can be simplified
to:
creatures = ArrayOfCreatures.new(num_of_creatures) do |i|
  creature_classes[rand(4)].new
end

It took me a few reads to appreciate, but I like that alot :slight_smile:

-Thufir