Variables
Programmers devote considerable time to naming data. Naming data provides two clear benefits. First, a good name makes code easier to understand and maintain. Consider this Ruby program that assigns meaningless names to its data:
b = a * 0.5
d = c / 2 * b * b
puts d
Likely you will not understand the intent behind this code. Pity the programmer who has to fix a bug in this code months after it is written. Contrast it with this code that uses meaningful names:
radius = diameter * 0.5
semicircle_area = Math::PI / 2 * radius * radius
puts semicircle_area
Second, names facilitate abstraction, which is movement away from the specific toward the general. For example, this code to calculate the cost of a taxed item is very specific:
cost = 17.99 * (1 + 0.075)
By naming the data with variables, the cost calculation may be expressed more abstractly:
price = 17.99
tax_rate = 0.075
cost = price * (1 + tax_rate)
To produce a different cost, you change only the variable assignments and not the abstract formula. A chunk of code whose data has been abstracted into variables is prepped for becoming a reusable function. The variables whose values will be changed become the function's parameters.
You introduce a new variable in a program with a declaration. Some languages provide a special declaration statement that announces the variable's type and name. For example, a declaration in Java looks like this:
double opacity;
This variable is given a value in an assignment statement:
opacity = 0.25;
The first time a variable is assigned is the variable's initialization. In languages like Java, which have explicit declarations, the declaration and initialization are often combined into a single statement:
double opacity = 0.25;
In Ruby, a declaration does not include the type and therefore looks exactly like an assignment:
opacity = 0.25
You can't tell by looking at this one line of code if it is an initialization or a reassignment of a variable declared elsewhere. Additionally, because there's no type associated with the variable in Ruby, it may be reassigned later to a value of a different type:
opacity = 0.25
opacity = "invisible"
Ruby's flexibility and economy of expression mean you can write code very quickly, but you can also write bugs very quickly. Many bugs will only be detected when the offending code runs. Thorough testing is paramount when writing Ruby programs.
Some languages allow you to leave a variable uninitialized and still refer to its value. Consider this C program that declares and prints variable a
:
This program compiles and runs. But its behavior is undefined, which means the C standard does not specify what number will be printed. Other languages detect references to uninitialized variables at compile time. This Kotlin program does not compile:
fun main() {
val a: Int
println(a)
}
What about Ruby?