Class constant methods

In several cases, i find myself wanting to create constants for a set of related classes. Each class has a different value, defined once, and then have the methods of the "abstract" class be able to reference the "classes" value.

I've tried doing this thing with methods and class variables and class constants, but the only one that works is methods. Like support_types in the following code from Watir:

     class TextField < Element
         def locate
             if @how == :from_object
                 ole_object = @what
             else
                 ole_object = @container.getObject(@how, @what, supported_types)
             end
             @o = ole_object
         end
         def supported_types
             return ["text", "password", "textarea"]
         end
         private :supported_types
    ...

     class Hidden < TextField
         def initialize(container, how, what)
             super
         end
         def supported_types
             return ["hidden"]
         end

I've found that the only way to get the behavior that i want is to use these kinds of "constant" methods. These seems inelegant, and i am wondering if there is a cleaner way of doing this kind of thing?

Here's another example of where i've done this kind of thing:

     class SelectLists < ElementCollections
         include CommonCollection
         def element_class; SelectList; end
         def element_tag; 'SELECT'; end
     end

Any suggestions. If i recall correctly, class constants didn't work because it wouldn't get the right scope. And class variables didn't have separate values for each of the classes.

Anyway, it seemed kludgy to have to use a method, when a constant or variable would do. Comments?

Bret

···

_____________________
  Bret Pettichord
  www.pettichord.com

Bret Pettichord wrote:

In several cases, i find myself wanting to create constants for a set of
related classes. Each class has a different value, defined once, and
then have the methods of the "abstract" class be able to reference the
"classes" value.

I've tried doing this thing with methods and class variables and class
constants, but the only one that works is methods. Like support_types in
the following code from Watir:

    class TextField < Element
        def locate
            if @how == :from_object
                ole_object = @what
            else
                ole_object = @container.getObject(@how, @what,
supported_types)
            end
            @o = ole_object
        end
        def supported_types
            return ["text", "password", "textarea"]
        end
        private :supported_types
   ...

    class Hidden < TextField
        def initialize(container, how, what)
            super
        end
        def supported_types
            return ["hidden"]
        end

I've found that the only way to get the behavior that i want is to use
these kinds of "constant" methods. These seems inelegant, and i am
wondering if there is a cleaner way of doing this kind of thing?

Here's another example of where i've done this kind of thing:

    class SelectLists < ElementCollections
        include CommonCollection
        def element_class; SelectList; end
        def element_tag; 'SELECT'; end
    end

Any suggestions. If i recall correctly, class constants didn't work
because it wouldn't get the right scope. And class variables didn't have
separate values for each of the classes.

Anyway, it seemed kludgy to have to use a method, when a constant or
variable would do. Comments?

Bret

_____________________
Bret Pettichord
www.pettichord.com

IIUC, this situation calls for constants with dynamic scoping, e.g.
mod::CONST.

    class Element < Object; end

    class TextField < Element
        SUPPORTED_TYPES = ["text", "password", "textarea"]
        def supported_types
          self.class::SUPPORTED_TYPES
        end
    end

    class Hidden < TextField
        SUPPORTED_TYPES = ["hidden"]
    end

    mod = Hidden

    p TextField.new.supported_types
    p Hidden.new.supported_types

__END__

Output:

    ["text", "password", "textarea"]
    ["hidden"]

···

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

You might want to register sub classes with inherited like in

class Base
  def self.inherited(cl) ( @sub ||= [] ) << cl end
end

And then use cl.const_get() to access actual values.

Btw, why does the super class need to know derived class's constants?

Kind regards

    robert

traits can be used in a similar way:

   harp:~ > cat a.rb
   require 'traits'

   class Element < Object
     class_trait 'supported_types'

     trait('supported_types'){ self.class::supported_types }
   end

   class TextField < Element
     supported_types %w[ text password textarea ]
   end

   class Hidden < TextField
     supported_types %w[ hidden ]
   end

   [ TextField, Hidden ].each{|klass| p klass => klass::new.supported_types }

   harp:~ > ruby a.rb
   {TextField=>["text", "password", "textarea"]}
   {Hidden=>["hidden"]}

cheers.

-a

···

On Wed, 7 Sep 2005, Joel VanderWerf wrote:

IIUC, this situation calls for constants with dynamic scoping, e.g.
mod::CONST.

   class Element < Object; end

   class TextField < Element
       SUPPORTED_TYPES = ["text", "password", "textarea"]
       def supported_types
         self.class::SUPPORTED_TYPES
       end
   end

   class Hidden < TextField
       SUPPORTED_TYPES = ["hidden"]
   end

   mod = Hidden

   p TextField.new.supported_types
   p Hidden.new.supported_types

__END__

Output:

   ["text", "password", "textarea"]
   ["hidden"]

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

Thanks, this was what i was looking for.

···

At 12:59 AM 9/7/2005, Joel VanderWerf wrote:

    class TextField < Element
        SUPPORTED_TYPES = ["text", "password", "textarea"]
        def supported_types
          self.class::SUPPORTED_TYPES
        end
    end

_____________________
  Bret Pettichord
  www.pettichord.com