Class constant methods

  • Thread starter Bret Pettichord
  • Start date
B

Bret Pettichord

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
 
J

Joel VanderWerf

Bret said:
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"]
 
R

Robert Klemme

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
 
A

Ara.T.Howard

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"]

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

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top