In this part of the Ruby tutorial, we will examine variables in more detail.
A variable is a place to store data. Each variable is given a unique name. There are some naming conventions which apply to variable names. Variables hold objects. More precisely, they refer to a specific object located in computer memory. Each object is of certain data type. There are built-in data types and there are custom-built data types. Ruby belongs to the family of dynamic languages. Unlike strongly typed languages like Java, C or Pascal, dynamic languages do not declare a variable to be of certain data type. Instead of that, the interpreter determines the data type at the moment of the assignment. Variables in Ruby can contain different values and different types of values over time.
Ruby is a case sensitive language. It means that age and Age are two different variable names. Most languages are case sensitive. BASIC is an exception, it is a case insensitive language. While we can create different names by changing the case of the characters, this practice is not recommended.
Variable names in Ruby can be created from alfanumeric characters and underscore (_) character. A variable cannot begin with a number. The interpreter can then easier distinguish between a literal number and a variable. Variable names cannot begin with a capital letter. If an identifier begins with a capital letter, it is considered to be a constant in Ruby.
Variable names should be meaningful. It is a good programming practice to choose descriptive names for variables. The programs are more readable then.
The following example is a slight modification of a previous example.
If a method takes parameters, a local variable is created for each of these parameters.
A method may be defined inside another method. The inner methods have their own local variables.
The last example of this section will present several demonstrations of a local scope.
The use of global variables is discouraged. Global variables easily lead to many programming errors. Global variables should be used only when there is a reason to do so. Instead of global variables, programmers are advised to use local variables whenever possible.
When a Ruby script starts, it has access to multiple predefined global variables. These globals are not considered harmful and help solve common programming jobs.
More global variables will be presented in the Predefined variables section of this chapter.
Instance variables are variables that belong to a particular object instance. Each object has its own object variables. Instance variables start with a @ sigil. Class variables belong to a specific class. All objects created from a particular class share class variables. Class variables start with @@ characters.
The
Both
The following example will deal with environment variables.
The
The true and false are values of a boolean datatype. From another point of view, they are instances of specific classes. This is because everything in Ruby is an object. This looks like unnecessarily complicated. But it is the consequence of the aforementioned Ruby idiom.
In the second example of this section, we will further look at the
The last example of the section will present other three pseudo variables.
The $? global variable stores the exit status of the last executed child process.
The $; variable has the default separator of the
In the final example, we show three global predefined variables which are used with regular expressions.
In this part of the Ruby tutorial, we looked deeper at the Ruby variables.
A variable is a place to store data. Each variable is given a unique name. There are some naming conventions which apply to variable names. Variables hold objects. More precisely, they refer to a specific object located in computer memory. Each object is of certain data type. There are built-in data types and there are custom-built data types. Ruby belongs to the family of dynamic languages. Unlike strongly typed languages like Java, C or Pascal, dynamic languages do not declare a variable to be of certain data type. Instead of that, the interpreter determines the data type at the moment of the assignment. Variables in Ruby can contain different values and different types of values over time.
#!/usr/bin/rubyThe term variable comes from the fact, that variables can take different values over time. Unlike constants. In the example above there is a variable called i. First it is assigned a value 5, later a different value 7. The values of a variable can vary over time.
i = 5
p i
i = 7
p i
Naming conventions
Ruby, like any other programming language, has some naming conventions for variable indentifiers.Ruby is a case sensitive language. It means that age and Age are two different variable names. Most languages are case sensitive. BASIC is an exception, it is a case insensitive language. While we can create different names by changing the case of the characters, this practice is not recommended.
#!/usr/bin/rubyThe code example defines two variables. I and i. They hold different values.
i = 5
p i
I = 7
p I
./case.rbOutput of the case.rb example.
5
7
Variable names in Ruby can be created from alfanumeric characters and underscore (_) character. A variable cannot begin with a number. The interpreter can then easier distinguish between a literal number and a variable. Variable names cannot begin with a capital letter. If an identifier begins with a capital letter, it is considered to be a constant in Ruby.
#!/usr/bin/rubyIn this script, we show a few valid variable names.
name = "Jane"
placeOfBirth = "Bratislava"
placeOfBirth = "Kosice"
favorite_season = "autumn"
n1 = 2
n2 = 4
n3 = 7
p name, placeOfBirth, favorite_season
p n1, n2, n3
Variable names should be meaningful. It is a good programming practice to choose descriptive names for variables. The programs are more readable then.
#!/usr/bin/rubyThe script shows three descriptive variable names. The place_of_birth is more descriptive to a programmer than e.g. pob. It is generally considered OK to choose simple variable names in loops.
name = "Jane"
place_of_birth = "Bratislava"
occupation = "student"
i = 5
while i > 0 do
puts name
i -= 1
end
Sigils
Variable identifiers can start with special characters also called sigils. A sigil is a symbol attached to an identifier. Variable sigils in Ruby denote variable scope. In contrast to Perl, where sigils denote data type. The Ruby variable sigils are $ and @.#!/usr/bin/rubyWe have four variables with different scopes. A scope is the range in which a variable can be referenced. We use special built-in methods to determine the scope of the variables.
tree_name = "pine"
$car_name = "Peugeot"
@sea_name = "Black sea"
@@species = "Cat"
p local_variables
p global_variables.include? :$car_name
p self.instance_variables
p Object.class_variables
tree_name = "pine"A variable without a sigil is a local variable. A local variable is valid only locally. For example inside a method, block or a module.
$car_name = "Peugeot"Global variables start with $ character. They are valid everywhere. The use of global variables should be limited in programs.
@sea_name = "Black sea"A variable name starting with a @ sigil is an instance variable. This variable is valid inside an object.
@@species = "Cat"Finally we have a class variable. This variable is valid for all instances of a specific class.
p local_variablesThe
local_variables
gives an array of all local variables defined in a specific context. Our context is Ruby toplevel. p global_variables.include? :$car_nameSimilarly, the
global_variables
produces an array of globals. We do not print all globals to the terminal, because there are many of them. Each Ruby script starts with a bunch of predefined variables. Instead of that, we call the include?
method of the array to check if our global is defined in the array. Also note that we are referencing variables with their symbols. (Symbols start with a colon character.) p self.instance_variablesThe
self
pseudo variable points to the receiver of the instance_variables
method. The receiver in our case is the main, the Ruby toplevel execution area. p Object.class_variablesFinally we have an array of class variables. The main is an instance of the
Object
class. $ ./sigils.rbOutput of the example. We see symbolic names of the variables.
[:tree_name]
true
[:@sea_name]
[:@@species]
Local variables
Local variables are variables that are valid within a local area of a Ruby source code. This area is also referred to as local scope. Local variables exist within the definition of a Ruby module, method, class.#!/usr/bin/rubyWe have a method called method1, which has one variable. The variable is local. This means that it is valid only within the method definition. We can refer to the x variable only between the method name and the
def method1
x = 5
p x
end
method1
p x
end
keyword. def method1This is the definition of the method1 method. Inside the method, we create a local x variable. We print the value of the variable to the terminal.
x = 5
p x
end
method1The method is called.
p xWe try to refer to a local variable outside the definition of the method. This leads to a
NameError
. The Ruby interpreter cannot find such identifier. $ ./locals.rbRunning the example gives the above output.
5
./locals.rb:11:in `<main>': undefined local variable
or method `x' for main:Object (NameError)
The following example is a slight modification of a previous example.
#!/usr/bin/rubyWe have two x variables. One is defined inside the method1 and the other one is defined outside. They are two distinct local variables. They do not clash with each other.
x = 5
def method1
x = 10
p x
end
method1
p x
x = 5We have created a local x variable, which holds value 5. The variable is valid in the local scope of the main execution area. It is not valid inside the method1.
def method1Inside the definition of the method1 a new local variable x is defined. It has value 10. It exists in the body of the method1 method. After the
x = 10
p x
end
end
keyword it ceases to exist. $ ./locals2.rbOutput.
10
5
If a method takes parameters, a local variable is created for each of these parameters.
#!/usr/bin/rubyWe have a method definition, which takes two values. The method returns the area of a rectangle.
def rectangle_area a, b
puts local_variables
return a * b
end
puts rectangle_area 5, 6
def rectangle_area a, bThe rectangle_area method takes two parameters. They are the sides of a rectangle, for which we calculate the area. Two local variables are automatically created for a, b identifiers. We call the
puts local_variables
return a * b
end
local_variables
method to see, what local variables we have in the method. puts rectangle_area 5, 6Here we pass two values to the method rectangle_area. The values will be assigned to two local variables, created inside the method.
$ ./parameters.rbThe output shows three things. The first two are the names of the local variables within the rectangle_area method. The third is the calculated area of the given rectangle.
a
b
30
A method may be defined inside another method. The inner methods have their own local variables.
#!/usr/bin/rubyIn this Ruby script, we create three methods. The method2 and method3 are inner methods. The method2 is defined inside the method1 and the method3 is defined inside method2. The local variables of each of the method is only accessible in the method, in which they were defined.
def method1
def method2
def method3
m5, m6 = 3
puts "Level 3"
puts local_variables
end
m3, m4 = 3
puts "Level 2"
puts local_variables
method3
end
m1, m2 = 3
puts "Level 1"
puts local_variables
method2
end
method1
$ ./lms.rbFrom the output we can see, that method1 has two local variables, m1 and m2. The inner method2 has m3, m4 local variables. The innermost method, method3 has m5, m6 local variables.
Level 1
m1
m2
Level 2
m3
m4
Level 3
m5
m6
The last example of this section will present several demonstrations of a local scope.
module ModuleMIn the code example, we create local variables inside a module, method, class and toplevel. The
m1, m2 = 4
puts "Inside module"
puts local_variables
end
def method1
v, w = 3
puts "Inside method"
puts local_variables
end
class Some
x, y = 2
puts "Inside class"
puts local_variables
end
method1
t1, t2 = 7
puts "Inside toplevel"
puts local_variables
local_variables
is a method of the Kernel
module, which returns all current local variables. module ModuleMA module is a collection of methods and constants. We create two local variables m1 and m2.
m1, m2 = 4
puts "Inside module"
puts local_variables
end
def method1Two local variables v, w are created in the method1 method.
v, w = 3
puts "Inside method"
puts local_variables
end
class SomeThe x, y local variables are created inside the definition of the Some class.
x, y = 2
puts "Inside class"
puts local_variables
end
t1, t2 = 7Finally two local variables that belong to the local scope of the Ruby toplevel.
$ ./locals3.rbThe output shows local variables for each local scope.
Inside module
m1
m2
Inside class
x
y
Inside method
v
w
Inside toplevel
t1
t2
Global variables
Global variables are valid everywhere in the script. They start with a $ sigil in Ruby.The use of global variables is discouraged. Global variables easily lead to many programming errors. Global variables should be used only when there is a reason to do so. Instead of global variables, programmers are advised to use local variables whenever possible.
#!/usr/bin/rubyIn the example we have a global variable $gb. We show that the variable can be referenced in a module, method, class and a toplevel. The global variable $gb is valid in all these entities.
$gb = 6
module ModuleM
puts "Inside module"
puts $gb
end
def method1
puts "Inside method"
puts $gb
end
class Some
puts "Inside class"
puts $gb
end
method1
puts "Inside toplevel"
puts $gb
puts global_variables.include? :$gb
$gb = 6A global variable $gb is created; it has value 6.
module ModuleMInside the defition of a module we print the value of the global variable.
puts "Inside module"
puts $gb
end
def method1Inside the defition of a method we print the value of the global variable.
puts "Inside method"
puts $gb
end
class SomeInside the defition of a class we print the value of the global variable.
puts "Inside class"
puts $gb
end
puts $gbFinally in the toplevel execution area we print the value of the global variable and , if the variable is in the array produced by the
puts global_variables.include? :$gb
global_variables
method. $ ./globals.rbThe output of the example confirms, that the global variable is accessible everywhere.
Inside module
6
Inside class
6
Inside method
6
Inside toplevel
6
true
When a Ruby script starts, it has access to multiple predefined global variables. These globals are not considered harmful and help solve common programming jobs.
#!/usr/bin/rubyThe script shows a
p $LOAD_PATH
p $:
$LOAD_PATH
global variable. The variable lists directories which are searched by load
and require
methods. The $:
is a short synonym for the $LOAD_PATH
name. More global variables will be presented in the Predefined variables section of this chapter.
Instance, class variables
In this section we will briefly cover instance and class variables. They will be described in Object-oriented programming chapter in more detail.Instance variables are variables that belong to a particular object instance. Each object has its own object variables. Instance variables start with a @ sigil. Class variables belong to a specific class. All objects created from a particular class share class variables. Class variables start with @@ characters.
#!/usr/bin/rubyWe create a custom Being class. The Being class has one class and one instance variable.
class Being
@@is = true
def initialize nm
@name = nm
end
def to_s
"This is #{@name}"
end
def does_exist?
@@is
end
end
b1 = Being.new "Being 1"
b2 = Being.new "Being 2"
b3 = Being.new "Being 3"
p b1, b2, b3
p b1.does_exist?
p b2.does_exist?
p b3.does_exist?
class BeingThe @@is is an class variable. This variable is shared by all instances of the Being class. The logic of this example is that Being is and NotBeing is not.
@@is = true
def initialize nmThe
@name = nm
end
initialize
method is a constructor. The method is called when the object is created. A @name instance variable is created. This variable is specific to a concrete object. def to_sThe
"This is #{@name}"
end
to_s
method is called, when the object is a parameter of a printing method, like p
or puts
. In our case, the method gives a short human readable description of the object. def does_exist?The does_exist? method returns the class variable.
@@is
end
b1 = Being.new "Being 1"Three objects from the Being class are created. Each of the objects has a different name. The name of the object will be stored in the instance method, which is unique to each object instance. This will be used in the
b2 = Being.new "Being 2"
b3 = Being.new "Being 3"
to_s
method, which give a short description of the object. p b1, b2, b3The
p
method takes the created objects as three parameters. It calls the to_s
method on each of these objects. p b1.does_exist?Finally, we call the does_exist? method of each of the instances and print their return values. The output of these three methods is the same, because each method returns the class variable.
p b2.does_exist?
p b3.does_exist?
$ ./icvars.rbOutput of the example. The first three messages are unique. The strings are stored in the instance variables of the objects. The true value is the value of the class variable, which is called three times.
This is Being 1
This is Being 2
This is Being 3
true
true
true
Environment & command-line variables
TheENV
constant gives access to environment variables. It is a Ruby hash. Each environment variable is a key to the ENV
hash. The
ARGV
constant holds command-line argument values. They are passed by the programmer when the script is launched. The ARGV
is an array which stores the arguments as strings. The $*
is an alias to the ARGV
. Both
ENV
and ARGV
are global constants. #!/usr/bin/rubyIn the script we loop through the
ARGV.each do |a|
puts "Argument: #{a}"
end
ARGV
array and print each of its values. $ ./commandline.rb 1 2 3We have given three command-line arguments. They are printed to the console. Each on a separate line.
Argument: 1
Argument: 2
Argument: 3
The following example will deal with environment variables.
#!/usr/bin/rubyThe script will print values of three environment variables to the terminal. The values depend on the OS settings of our operating system.
puts ENV['SHELL']
puts ENV['LANG']
puts ENV['TERM']
$ ./environment.rbA sample output.
/bin/bash
en_US.utf8
xterm
Pseudo variables
Ruby has a few variables which are called pseudo variables. They are different from regular variables. We cannot assign values to pseudo variables.The
self
is the receiver of the current method. The nil
is the sole instance of the NilClass
. It represents the absense of a value. The true
is the sole instance of the TrueClass
. It represents boolean true. The false
is a sole instance of FalseClass
. It represents boolean false. The true and false are values of a boolean datatype. From another point of view, they are instances of specific classes. This is because everything in Ruby is an object. This looks like unnecessarily complicated. But it is the consequence of the aforementioned Ruby idiom.
#!/usr/bin/rubyThis is an example of pseudo variables. We print all four pseudo variables with the
p self
p nil
p true
p false
p self.class
p nil.class
p true.class
p false.class
p
method. Then we find out the class name for all of them. p selfIn this context, the
self
pseudo variable returns the main execution context. $ ./pseudo.rbExample output.
main
nil
true
false
Object
NilClass
TrueClass
FalseClass
In the second example of this section, we will further look at the
self
. #!/usr/bin/rubyAs we have said, the
class Some
puts self
end
class Other
puts self
end
puts self
self
gives the receiver of the current method. The above example shows three examples of different receivers. class SomeThe receiver is the class called Some.
puts self
end
class OtherHere is another receiver. A class named Other.
puts self
end
puts selfAnd the third receiver is the Ruby toplevel.
$ ./pseudoself.rbExample output.
Some
Other
main
The last example of the section will present other three pseudo variables.
#!/usr/bin/rubyThe above example shows
if true
puts "This message is shown"
end
if false
puts "This message is not shown"
end
p $name
p $age
true
, false
and nil
pseudo variables at work. if trueThe
puts "This message is shown"
end
true
is used in boolean expression. The message is always printed. if falseThis message is never printed. The condition is not met. In the boolean expression we always get a negative value.
puts "This message is not shown"
end
p $nameIf global values are referenced and have not been initialized, they contain the
p $age
nil
pseudo variable. It stands for the absence of a value. $ ./pseudo2.rbOutput of the pseudo2.rb Ruby script.
This message is shown
nil
nil
Predefined variables
Ruby has plenty of predefined global variables. This is a heritage of Perl language. Ruby was influenced strongly by Perl. They are at disposal when the Ruby script starts. We have a few examples for the predefined Ruby variables.#!/usr/bin/rubyThree predefined variables have been used. $0, $* and $$. The $0 stores the current script name. The $* variable stores command-line arguments. And the $$ stores the PID (process id) of the script.
print "Script name: ", $0, "\n"
print "Command line arguments: ", $*, "\n"
puts "Process number of this script: #{$$}"
$ ./predefined.rb 1 2 3Sample output.
Script name: ./predefined.rb
Command line arguments: ["1", "2", "3"]
Process number of this script: 3122
The $? global variable stores the exit status of the last executed child process.
#!/usr/bin/rubyWe run two external child processes and check their exit status with the $? variable.
system 'echo "Ruby"'
puts $?
%x[exit '1']
puts $?
system 'echo "Ruby"'With the use of the
puts $?
system
method we start a child process. It is an echo bash command, which prints a message to the terminal. %x[exit '1']In the second case we execute exit bash command with status 1.
puts $?
$ ./predefined2.rbThe first child process terminates with status 0, the second with exit status 1.
Ruby
pid 3131 exit 0
pid 3133 exit 1
The $; variable has the default separator of the
split
method of the String
class. #!/usr/bin/rubyWe use the $; variable to control, how the string is cut with the
str = "1,2,3,4,5,6,7"
p str.split
$; = ","
p str.split
split
method. The method takes a parameter, which tells where the string should be split. If the parameter is omitted, than the value from the $; is used. $; = ","We specify a delimiter for the $; variable. The split method does not take a parameter, so the value of the $; is used.
p str.split
$ ./predefined3.rbIn the first case, the string was not split. In the second case, the string was split correctly, as we have intended.
["1,2,3,4,5,6,7"]
["1", "2", "3", "4", "5", "6", "7"]
In the final example, we show three global predefined variables which are used with regular expressions.
#!/usr/bin/rubyWhen we apply the =~ operator on a string, Ruby sets some variables. The $& variable has a string that matched the last last regular expression match. The $` has a string preceding $& and the $’ has a string following the $&.
"Her name is Jane" =~ /name/
p $`
p $&
p $'
$ ./predefined4.rbExample output.
"Her "
"name"
" is Jane"
In this part of the Ruby tutorial, we looked deeper at the Ruby variables.
0 comments:
Post a Comment