Friday, March 20, 2020

Global Variables in Ruby

Global Variables in Ruby Global Variables are variables that may be accessed from anywhere in the program regardless of scope. Theyre denoted by beginning with a $ (dollar sign) character. However, the use of global variables is often considered un-Ruby, and you will rarely see them. Defining Global Variables Global variables are defined and used like any other variable. To define them, simply assign a value to them and begin using them. But, as their name suggests, assigning to global variables from any point in the program has global implications. The following program demonstrates this. The method will modify a global variable, and that will affect how the second method runs. $speed 10 def accelerate $speed 100 end def pass_speed_trap if $speed 65 # Give the program a speeding ticket end end accelerate pass_speed_trap Unpopular So why is this un-Ruby and why dont you see global variables very often? Put simply, it breaks encapsulation. If any one class or method can modify the state of the global variables at will with no interface layer, any other classes or methods that rely on that global variable may behave in an unexpected and undesirable manner. Further, such interactions can be very difficult to debug. What modified that global variable and when? Youll be looking through quite a lot of code to find what did it, and that could have been avoided by not breaking the rules of encapsulation. But thats not to say that global variables are never used in Ruby. There are a number of special global variables with single-character names (a-la Perl) that can be used throughout your program. They represent the state of the program itself, and do things like modify the record and field separators for all gets methods. Global Variables $0 - This variable, denoted by $0 (thats a zero), holds the name of the top-level script being executed. In other words, the script file that was run from the command line, not the script file that holds the currently executing code. So, if script1.rb was run from the command line, it would hold script1.rb. If this script requires script2.rb, $0 in that script file would also be script1.rb. The name $0 mirrors the naming convention used in UNIX shell scripting for the same purpose.$* - The command-line arguments in an array denoted by $* (dollar sign and asterisk). For example, if you were to run ./script.rb arg1 arg2, then $* would be equivalent to %w{ arg1 arg2 }. This is equivalent to the special ARGV array and has a less descriptive name, so it is rarely used.$$ - The interpreters process ID, denoted by $$ (two dollar signs). Knowing ones own process ID is often useful in daemon programs (which run in the background, unattached from any terminal) or system services. However, this gets a bit more complicated when threads are involved, so be wary of using it blindly. $/ and $\ - These are the input and output record separators. When you read objects using gets and print them using puts, it uses these to know when a complete record has been read, or what to print between multiple records. By default, these should be the newline character. But since these affect the behavior of all IO objects, theyre rarely used, if at all. You may see them in smaller scripts where breaking the encapsulation rules is not an issue.$? - The exit status of the last child process executed. Of all the variables listed here, this is probably the most useful. The reason for this is simple: you cant get the exit status of child processes by their return value from the system method, only true or false. If you must know the actual return value of the child process, you need to use this special global variable. Again, the name of this variable is taken from the UNIX shells.$_ - The last string read by gets. This variable may be a point of confusion for those coming to Ruby f rom Perl. In Perl, the $_ variable means something similar, but totally different. In Perl, $_ holds the value of the last statement and in Ruby it holds the string returned by the previous gets invocation. Their usage is similar, but what they really hold is very different. You dont often see this variable either (come to think of it, you rarely see any of these variables), but you may see them in very short Ruby programs that process text. In short, youll rarely see global variables. Theyre often bad form (and un-Ruby) and only really useful in very small scripts, where the full implication of their use can be fully appreciated. There are a few special global variables that can be used, but for the most part, they arent used. You dont really need to know all that much about global variables to understand most Ruby programs, but you should at least know that theyre there.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.