Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Why defining a constant in a method is not allowed but usingself.class.const_set is allowed?

Reply
Thread Tools

Why defining a constant in a method is not allowed but usingself.class.const_set is allowed?

 
 
Iñaki Baz Castillo
Guest
Posts: n/a
 
      04-30-2011
Hi, assinging a value to a constant within a method is not allowed
(SyntaxError:: dynamic constant assignment) but I can use
self.class.const_set within a method. Which is the difference?

--=20
I=C3=B1aki Baz Castillo
<(E-Mail Removed)>

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      04-30-2011
On 30.04.2011 21:25, Iaki Baz Castillo wrote:
> Hi, assinging a value to a constant within a method is not allowed
> (SyntaxError:: dynamic constant assignment) but I can use
> self.class.const_set within a method. Which is the difference?


You described the difference pretty accurately. It is quite common for
Ruby to forbid doing bad things directly while still leaving a way to do
it nevertheless (just think of private methods and #send).

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
 
 
 
Iñaki Baz Castillo
Guest
Posts: n/a
 
      04-30-2011
2011/4/30 Robert Klemme <(E-Mail Removed)>:
> On 30.04.2011 21:25, I=C3=B1aki Baz Castillo wrote:
>>
>> Hi, assinging a value to a constant within a method is not allowed
>> (SyntaxError:: dynamic constant assignment) but I can use
>> self.class.const_set within a method. Which is the difference?

>
> You described the difference pretty accurately. =C2=A0It is quite common =

for Ruby
> to forbid doing bad things directly while still leaving a way to do it
> nevertheless (just think of private methods and #send).


Ok. Then one question more: why is not possible to reassing a value to
a constant (even using self.class.const_set)? Is there internal issue
with it? I get a warning doing it (I suppose it depends on $safe
value), but what is the real problem with it?

Thanks a lot.

--=20
I=C3=B1aki Baz Castillo
<(E-Mail Removed)>

 
Reply With Quote
 
7stud --
Guest
Posts: n/a
 
      04-30-2011
"I=C3=B1aki Baz Castillo" <(E-Mail Removed)> wrote in post #995996:
>
> Ok. Then one question more: why is not possible to reassing a value to
> a constant


Why do you want to change a *constant*? ruby has variables for that.

-- =

Posted via http://www.ruby-forum.com/.=

 
Reply With Quote
 
Iñaki Baz Castillo
Guest
Posts: n/a
 
      04-30-2011
2011/4/30 7stud -- <(E-Mail Removed)>:
> "I=C3=B1aki Baz Castillo" <(E-Mail Removed)> wrote in post #995996:
>>
>> Ok. Then one question more: why is not possible to reassing a value to
>> a constant

>
> Why do you want to change a *constant*? =C2=A0ruby has variables for that=

 
Reply With Quote
 
Christopher Dicely
Guest
Posts: n/a
 
      04-30-2011
On Sat, Apr 30, 2011 at 12:58 PM, I=C3=B1aki Baz Castillo <(E-Mail Removed)> w=
rote:
> 2011/4/30 Robert Klemme <(E-Mail Removed)>:
>> On 30.04.2011 21:25, I=C3=B1aki Baz Castillo wrote:
>>>
>>> Hi, assinging a value to a constant within a method is not allowed
>>> (SyntaxError:: dynamic constant assignment) but I can use
>>> self.class.const_set within a method. Which is the difference?

>>
>> You described the difference pretty accurately. =C2=A0It is quite common=

for Ruby
>> to forbid doing bad things directly while still leaving a way to do it
>> nevertheless (just think of private methods and #send).

>
> Ok. Then one question more: why is not possible to reassing a value to
> a constant (even using self.class.const_set)? Is there internal issue
> with it? I get a warning doing it (I suppose it depends on $safe
> value), but what is the real problem with it?


It is possible. As you note, it produces a warning, because more than
one assignment to a constant indicates something that is likely to be
an error (since the use of a constant rather than a variable implies
that the value is intended to be constant once defined.)

At any rate, sure, constant (or global variable) lookup is maybe twice
as fast as accessing an instance variable of another object (class or
otherwise) through a simple getter method (though maybe not; it seems
close to that on Windows Ruby 1.9.2, but the ratio seems a lot closer
on JRuby 1.6.1 [which makes sense, since JRuby has done a lot of work,
IIRC, to optimize method calls, which are where the extra time seems
to be], and the results may differ for other implementations), and you
might save a tenth of a microsecond or so (on fairly modest current
hardware) per access from outside of the object to which the value
belongs, but are you really spending so much of your programs time on
that kind of access where speeding that access up is going to make a
difference?

Since looking up instance variables that are in scope is about as fast
as looking up remote constants, you may (depending on the access
pattern and frequency of change involved) be able to get a similar
speedup without abusing constants simply by caching the value of the
remote attribute in a local instance variable of the objects consuming
it, and registering them as listeners that are notified on updates to
the value.

OTOH, if you absolutely must redefine constants and avoid producing
warnings (without actually changing the settings affecting warning
levels), its simple enough to do (Ruby rarely stops you from doing
things):

class C
KONST =3D 123
def self.konst=3D(val)
remove_const :KONST
const_set :KONST, val
end
end

 
Reply With Quote
 
Iñaki Baz Castillo
Guest
Posts: n/a
 
      04-30-2011
2011/5/1 Christopher Dicely <(E-Mail Removed)>:
> It is possible. As you note, it produces a warning, because more than
> one assignment to a constant indicates something that is likely to be
> an error (since the use of a constant rather than a variable implies
> that the value is intended to be constant once defined.)


Yes, I understand that redeining a constant is not "good" in any
language, just wondering why Ruby, being so flexible, also behaves
like others.


> At any rate, sure, constant (or global variable) lookup is maybe twice
> as fast as accessing an instance variable of another object (class or
> otherwise) through a simple getter method


Yes, I assume it occurs because Ruby must perform two lookups:

1) the method
2) the attribute returned by the method


> but are you really spending so much of your programs time on
> that kind of access where speeding that access up is going to make a
> difference?


Well, is just minimum of course, I just wanted to study it. or sure
accessing an attribute (through a method) will not be the bottleneck
of my application


> Since looking up instance variables that are in scope is about as fast
> as looking up remote constants, you may (depending on the access
> pattern and frequency of change involved) be able to get a similar
> speedup without abusing constants simply by caching the value of the
> remote attribute in a local instance variable of the objects consuming
> it, and registering them as listeners that are notified on updates to
> the value.


It seems not very suitable in my application. Basically I get a conf
file and want to store configuration data in constants (for faster
lockup). But I also need to change those values in realtime.

But as said before, I'll probasbly move to attribute variables.



> OTOH, if you absolutely must redefine constants and avoid producing
> warnings (without actually changing the settings affecting warning
> levels), its simple enough to do (Ruby rarely stops you from doing
> things):
>
> class C
> =C2=A0KONST =3D 123
> =C2=A0def self.konst=3D(val)
> =C2=A0 =C2=A0remove_const :KONST
> =C2=A0 =C2=A0const_set :KONST, val
> =C2=A0end
> end


Interesting, thanks a lot


--=20
I=C3=B1aki Baz Castillo
<(E-Mail Removed)>

 
Reply With Quote
 
Phillip Gawlowski
Guest
Posts: n/a
 
      05-01-2011
On Sun, May 1, 2011 at 1:48 AM, I=F1aki Baz Castillo <(E-Mail Removed)> wrote:
>
> Yes, I understand that redeining a constant is not "good" in any
> language, just wondering why Ruby, being so flexible, also behaves
> like others.


It's called a "constant". What would you expect it to be? Ever
changing like like the wind, or steady and everlasting like the
mountains?*

Ruby gives you the mountain--and the tools to change the mountain into
a sculpture.

It's the Principle Of Least Surprise (To Matz) hard at work.

> It seems not very suitable in my application. Basically I get a conf
> file and want to store configuration data in constants (for faster
> lockup). But I also need to change those values in realtime.


Well, before making constants mutable, I'd see if they actually are a
worthwhile target of optimization (and the possible breakage this
introduces).

Maybe a configuration Hash is an acceptable compromise between lookup
speed and mutability?


* I know, mountains erode, and winds actually have patterns to them,
but allow me to be a bit flowery for once.

--=20
Phillip Gawlowski

Though the folk I have met,
(Ah, how soon!) they forget
When I've moved on to some other place,
There may be one or two,
When I've played and passed through,
Who'll remember my song or my face.

 
Reply With Quote
 
Iñaki Baz Castillo
Guest
Posts: n/a
 
      05-01-2011
2011/5/1 Phillip Gawlowski <(E-Mail Removed)>:
> Maybe a configuration Hash is an acceptable compromise between lookup
> speed and mutability?


Humm, yes, having a HASH constant containing a hash is faster than
accessing instance variables within a class. Just a bit, but faster

So I'll use it, something like:

module MyApp
CONFIGURATION =3D {}
end

Thanks.

--=20
I=C3=B1aki Baz Castillo
<(E-Mail Removed)>

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      05-01-2011
On 01.05.2011 02:24, Iaki Baz Castillo wrote:
> 2011/5/1 Phillip Gawlowski<(E-Mail Removed)>:
>> Maybe a configuration Hash is an acceptable compromise between lookup
>> speed and mutability?

>
> Humm, yes, having a HASH constant containing a hash is faster than
> accessing instance variables within a class. Just a bit, but faster


You never mentioned a performance problem you are trying to solve.
Could be that you are worrying too much about an irrelevant detail.

> So I'll use it, something like:
>
> module MyApp
> CONFIGURATION = {}
> end


This might be a corner case but I would generally advice to not use
global variables (or constants) for this. The reason is simply that you
loose a lot of flexibility. You can only ever have one active
configuration at a time - and you cannot change it concurrently as well.

It may be OK for a small script or application but if you make that
design a habit you might run into problems later. Generally it is
better to provide configuration and other information from the outside
because that also makes testing easier. You can pass in whatever mock
you want to use to test a particular feature. If OTOH instances decide
themselves where to get the information from (i.e. the global variable /
constant) you are out of luck (or you need to patch methods of the class
under test while testing which is generally not a good idea because then
you don't test any more what will be productive eventually).

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/


 
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
Rational argument for not defining string constant for empty string? david.karr Java 21 03-14-2010 07:39 PM
"error C2057: expected constant expression", "error C2466: cannot allocate an array of constant size 0". Why doesn't my simple program work??? hn.ft.pris@gmail.com C++ 13 01-22-2007 02:03 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Msxml2.XMLHTTP object's send method throwing HTTP /1.1 405 - Method not allowed error. RK Javascript 5 08-08-2004 08:52 PM
defining or not defining destructors johny smith C++ 8 07-02-2004 08:51 AM



Advertisments