Friday, December 22, 2006
Ruby: Constant values
I generally use constants in Ruby for the following two situations: Markers or Constant values.
Markers are used as a standard for comparison.
Constant values are global values that should never change during the life of your application.
Markers are used as a standard for comparison.
module CreditCardTypesMarkers are initialized to a value; however, that value is unimportant as long as it is unique. Markers are generally used in an application within conditional statements.
Visa = 0
Mastercard = 1
end
case card.typeNote: you can also use symbols as markers, but I prefer constants. This preference is based on the fact that if I mistype CreditCardTypes::Vissa it will fail fast; however, if I mistype :credit_card_type_vissa, I will get a possibly hard to find bug.
when CreditCardTypes::Visa then VisaLuhnValidator
when CreditCardTypes::Mastercard then MastercardLuhnValidator
end
Constant values are global values that should never change during the life of your application.
module MathValuesConstant values can be used throughout applications to ensure that the same value is consistently used.
PI = 3.14
end
circumference = circle.diameter * MathValues::PIBased on these usages, I'm a bit concerned about some behavior I recently found.
irb(main):019:0> module MathVariablesWarning? This means anyone can redefine my constants at any time? Did I do something wrong? Does anyone else think this is dangerous?
irb(main):020:1> PI = 3.14
irb(main):021:1> end
=> 3.14
irb(main):022:0> module MathVariables
irb(main):023:1> PI = 3.14159265
irb(main):024:1> end
(irb):23: warning: already initialized constant PI
=> 3.14159265
Comments:
<< Home
Dangerous? Yes. It's a very, very sharp knife. That's why there's a warning when it happens.
There's nothing out and out wrong with it though. What is a constant except a variable that we agree not to touch?
There's nothing out and out wrong with it though. What is a constant except a variable that we agree not to touch?
Remember that Ruby is designed for giving maximum power to professional programmers. It is not designed to give armies of morons an opportunity to create some kind of reliable code (what Java is for). So, well, if sometimes you really need to do something dangerous (kinds of goto, one line commands, redefine methods/constants, rough fixes and workarounds) you have a total ability to do this. There are no stupid restrictions just because of their potentional danger. This is by design, so this is a feature, not a bug :)
Actually, the constant part is the reference to the object, it should not be changed, but the interpreter will just warn you.
It is ok, to change the object that is referenced by the constant.
After struggling with "final" stuff in Java, I really prefer having control and not letting the designers of the language impose useless restrictions.
It is ok, to change the object that is referenced by the constant.
After struggling with "final" stuff in Java, I really prefer having control and not letting the designers of the language impose useless restrictions.
This irked me somewhat when I first walked up to Ruby. It was a remnant of my static type brainwashing. Three things mitigate against this being a real problem. 1. The warning. You could argue it should be an exception, but in reality, how would that be any different in the case where some other programmer silently caught the exception? Which brings me to number 2) Don't work with morons. Only morons silently catch exceptions and continue and only morons change constant values used in that way. Which brings me to 3) Neither of us is a moron, so you'll be happy to know that anecdotally this has never happened to me. It's really because constants stand out in Ruby anyway, what with their upcase, and how often are you likely to have a constant as an L-value in your code? (See #2)
Many of the potential oddities we're taught to fear in the statically typed world are exposed as FUD in dynamic languages. Don't sweat the small stuff. :)
Many of the potential oddities we're taught to fear in the statically typed world are exposed as FUD in dynamic languages. Don't sweat the small stuff. :)
I'm cool with everything said, and I too prefer enough rope to hang myself. I'll concede that conceptually it is okay, but I think I would prefer a different name since the value isn't constant.
In the end, this surely isn't reason enough for me to give up on ruby, but I think if nothing else the name of this concept has room to improve.
Thanks for the feedback.
Jay
In the end, this surely isn't reason enough for me to give up on ruby, but I think if nothing else the name of this concept has room to improve.
Thanks for the feedback.
Jay
Maybe, uh... sticky variables?
I seem to remember from my reading of the Pickaxe that the CONSTANT_NAMING causes the interpreter to look up the variable somewhat differently. And... it doesn't look like I brought my Pickaxe home so I can't look it up.
I seem to remember from my reading of the Pickaxe that the CONSTANT_NAMING causes the interpreter to look up the variable somewhat differently. And... it doesn't look like I brought my Pickaxe home so I can't look it up.
Changing names is not a very good thing. Everyone knows that Ruby is totally dynamic and there could not be real constants at all, anywhere. Getting bold about naming could lead to weird disclaimers, like MutableClass, RedefinableMethod, or even putSomethingRespondingTo_to_s() instead of simply puts(). Let this nonsense stuff to Javaists and do things that matter instead. Thank you and happy new year.
It was a bit strange to me at first, also, but it makes sense when you consider that just about everything in Ruby can be redefined in some way. I don't even think it would be possible for constants to truly be "constant" and still allow classes to be redefined or even removed at runtime.
Ruby: You'll shoot your eye out.
Ruby: You'll shoot your eye out.
The only true constant is change. Most of our accepted 'constants' are actually only conventions. If you 'expect' your HOURS_PER_DAY == 24, then your code will be lost when a meteor changes the speed of the Earth's rotation. :-P
Here's a weird one we discovered today:
MYCONST="bob"
myvar=MYCONST
myvar << " and fred"
MYCONST and myvar are now == "bob and fred" without a warning. Clearly this must be a bug? (btw- this is with ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux])
Post a Comment
MYCONST="bob"
myvar=MYCONST
myvar << " and fred"
MYCONST and myvar are now == "bob and fred" without a warning. Clearly this must be a bug? (btw- this is with ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux])
<< Home




