Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Is there a way to make class and object constants in Ruby?

Reply
Thread Tools

Is there a way to make class and object constants in Ruby?

 
 
Xeno Campanoli
Guest
Posts: n/a
 
      04-15-2010
I am reading up in other areas, and it occurs to me much of the items I have as
class and object variables really should be constants, but ideally still in the
class or object context. Is there a way to do this?

xc
--
"It's the preponderance, stupid!" - Professor Stephen Schneider, IPCC member

 
Reply With Quote
 
 
 
 
Thomas Volkmar Worm
Guest
Posts: n/a
 
      04-15-2010
Am Wed, 14 Apr 2010 20:00:54 -0500 schrieb Xeno Campanoli:

> I am reading up in other areas, and it occurs to me much of the items I
> have as class and object variables really should be constants, but
> ideally still in the class or object context. Is there a way to do
> this?
>
> xc


In class context you could do:

class MyClass

MYCONSTANT=6

def initialize
puts MYCONSTANT
end

end


But I wonder, whether it makes sense at all to have constants at object
level. This sounds weird to me.

Thomas
 
Reply With Quote
 
 
 
 
Josh Cheek
Guest
Posts: n/a
 
      04-15-2010
[Note: parts of this message were removed to make it a legal post.]

On Wed, Apr 14, 2010 at 8:00 PM, Xeno Campanoli <(E-Mail Removed)>wrote:

> I am reading up in other areas, and it occurs to me much of the items I
> have as class and object variables really should be constants, but ideally
> still in the class or object context. Is there a way to do this?
>
> xc
> --
> "It's the preponderance, stupid!" - Professor Stephen Schneider, IPCC
> member
>
>

Variables that begin with capital letters are constants

initial_constants = Module.constants
class MyClass
MY_FAVOURITE_NUMBER = 12
MyFavouriteNumber = 12
end
Module.constants - initial_constants # => [:MyClass]
MyClass.constants # => [:MY_FAVOURITE_NUMBER, :MyFavouriteNumber]


So you can see that classes are already constants, and an example of how to
create constants within a class.

In Ruby, this really means that the reference may not be changed (or at
least you will be warned if you try to do so), not that the object being
referenced may not be mutated.

class MyClass
MyFavouriteNumber = 12
MyFavouriteNumber = 13 # !> already initialized constant MyFavouriteNumber
MyFavouriteNumber # => 13
end

If you change your constant, you will know, it will warn you (ie, it won't
happen by accident). If your code breaks because of this... well... you'll
have a pretty good idea where to look. While Ruby is dynamic enough to make
such a change, it is not something you should do. If you need to change your
constants, then they shouldn't be constants.

If you really need your data to not change, to the point where you don't
even want to allow yourself the opportunity to do so, you can freeze it, and
it will throw an exception

class MyClass
MyFavouriteWord = "ambivalent"
MyFavouriteWord << 'l'
MyFavouriteWord # => "ambivalentl"
MyFavouriteWord.freeze
MyFavouriteWord << 'y'
MyFavouriteWord # =>
end
# ~> -:6:in `<class:MyClass>': can't modify frozen string (RuntimeError)
# ~> from -:1:in `<main>'



But as far as I am aware, there is no way to recursively free any references
it has (probably a good thing, you could recursively freeze your entire
program)

class MyClass

SomeArray = [ 'abc' , 'def' ].freeze
SomeArray # => ["abc", "def"]

begin
SomeArray << 'ghi'
rescue => e
e # => #<RuntimeError: can't modify frozen array>
end

SomeArray.last # => "def"
SomeArray.last << 'ghi'
SomeArray.last # => "defghi"

end



Generally, constants are used for data that should be hard coded in, you use
a constant so that you can easily change it later, like using a macro in C.
You can then drop it into your code, and it is replaced with the actual
value (you can redefine macros too). And they are also used for keeping
important references, like the constant STDIN. We can change the global we
use as stdin, but we don't want to lose track the actual stdin, so we keep
it in the constant.

STDIN # => #<IO:<STDIN>>
$stdin # => #<IO:<STDIN>>

$stdin = DATA # => #<File:untitled>
gets # => "this is the data\n"

$stdin = STDIN # => #<IO:<STDIN>>

__END__
this is the data

 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      04-15-2010
[Note: parts of this message were removed to make it a legal post.]

On Wed, Apr 14, 2010 at 8:40 PM, Thomas Volkmar Worm <(E-Mail Removed)> wrote:

> Am Wed, 14 Apr 2010 20:00:54 -0500 schrieb Xeno Campanoli:
>
> > I am reading up in other areas, and it occurs to me much of the items I
> > have as class and object variables really should be constants, but
> > ideally still in the class or object context. Is there a way to do
> > this?
> >
> > xc

>
> In class context you could do:
>
> class MyClass
>
> MYCONSTANT=6
>
> def initialize
> puts MYCONSTANT
> end
>
> end
>
>
> But I wonder, whether it makes sense at all to have constants at object
> level. This sounds weird to me.
>
> Thomas
>
>

I do for things that don't (or shouldn't) change. For example, I'm working
on a Rails project where the admin can assign a level of trust to a user
such that they can post images directly to the main page from Twitter. The
database doesn't inherently support enumerated types, so the attribute is an
integer, then I have class level constants that map those values to their
meanings, and a set of methods that allow you to get booleans back when
asking if that user is able to do that authorized thing, and they are
embedded into named scopes so that I can pull all users who have this
authorization level, or that authorization level, and so forth. So I just
store a single integer in the database, but my application interprets it the
same across every instance.

 
Reply With Quote
 
Xeno Campanoli
Guest
Posts: n/a
 
      04-19-2010
Thank you Josh and Thomas. The source of this question is my study of Erlang,
where all 'Variables' do not vary after the initial assignment. I realized when
reading up on the language that there are many areas in my classes where the
thing I use, especially with Object Variables, are effectively constants, so I
would do best to have them as actual constants. It turns out there is a lot of
value in knowing that something cannot change, even if it can change but will
have at least an obvious error. I don't expect to Erlangize my programs, but I
have already identified things I can do to make my stuff safer and clearer just
by making class and object variables into constants. Too bad there is not a
special prefix for these as there is for the variables. That would be nice for
referencing things. Still, no big deal.

xc



Josh Cheek wrote:
> On Wed, Apr 14, 2010 at 8:40 PM, Thomas Volkmar Worm <(E-Mail Removed)> wrote:
>
>> Am Wed, 14 Apr 2010 20:00:54 -0500 schrieb Xeno Campanoli:
>>
>>> I am reading up in other areas, and it occurs to me much of the items I
>>> have as class and object variables really should be constants, but
>>> ideally still in the class or object context. Is there a way to do
>>> this?
>>>
>>> xc

>> In class context you could do:
>>
>> class MyClass
>>
>> MYCONSTANT=6
>>
>> def initialize
>> puts MYCONSTANT
>> end
>>
>> end
>>
>>
>> But I wonder, whether it makes sense at all to have constants at object
>> level. This sounds weird to me.
>>
>> Thomas
>>
>>

> I do for things that don't (or shouldn't) change. For example, I'm working
> on a Rails project where the admin can assign a level of trust to a user
> such that they can post images directly to the main page from Twitter. The
> database doesn't inherently support enumerated types, so the attribute is an
> integer, then I have class level constants that map those values to their
> meanings, and a set of methods that allow you to get booleans back when
> asking if that user is able to do that authorized thing, and they are
> embedded into named scopes so that I can pull all users who have this
> authorization level, or that authorization level, and so forth. So I just
> store a single integer in the database, but my application interprets it the
> same across every instance.
>



--
"It's the preponderance, stupid!" - Professor Stephen Schneider, IPCC member

 
Reply With Quote
 
Chris Hulan
Guest
Posts: n/a
 
      04-20-2010
To make objects immutable you can 'freeze' them. After being frozen
any attempt
to change will result in an error:
>> x = 'test'

=>
"test"
>> x.freeze

=>
"test"
>> x[0] = 'w'

RuntimeError: can't modify frozen string
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
Prefixes _ and __ for object and class constants proposed Xeno Campanoli Ruby 2 01-25-2008 07:53 PM
Is there interest in this? : get object from its object-specific class? Rick DeNatale Ruby 0 03-15-2007 10:14 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Is there a clean way to export all constants from a module? Steve Allan Perl Misc 5 07-29-2003 07:08 PM



Advertisments