101 - variable scope Flashcards
What will the following code print, and why?
array = [1, 2, 3]
array.each do |element|
a = element
end
puts a
=> undefined local variable or method `a’ for main:Object (NameError)
Yes a is defined inside the block without being assigned a value outside first. Throws an error message.
What will the following code print, and why?
a = 7 array = [1, 2, 3]
array.each do |a|
a += 1
end
puts a
=> 7
This problem demonstrates shadowing. Shadowing occurs when a block argument hides a local variable that is defined outside the block. Since the outer a is shadowed, the a += 1 has no effect on it. In fact, that statement has no effect at all.
What will the following code print, and why?
a = 7 array = [1, 2, 3]
def my_value(ary) ary.each do |b| a += b end end
my_value(array)
puts a
=> undefined local variable or method `a’ for main:Object (NameError)
a at the top level is not visible inside the block because the block is inside my_value, and methods are self-contained with respect to local variables. Since the outer a is not visible inside my_value, it isn’t visible inside the block.
What will the following code print, and why?
a = 7
def my_value(b)
b += 10
end
my_value(a)
puts a
=> 7
Assignment, including assignment operators like +=, does not mutate a variable, but changes the object that variable references. Since only the reference for b is changed, no alteration is made to the value referenced by a. Thus, a is still equal to 7 at the time of the puts.
Another way to look at this is that numbers in ruby are immutable. Thus, there is no way for my_value to mutate the value referenced by b. Thus, a is not changed by my_value.
What will the following code print, and why?
a = 7
def my_value(a)
a += 10
end
my_value(a)
puts a
=> 7
a += 10 is reassignment, however a = 7 is top level scope and is not available inside the method.
Variables outside the method are not visible inside the method, so the top level a is not available inside my_value. Furthermore, variables inside the method are not visible outside the method, so the a inside my_value is a local variable with no top-level visibility.
What will the following code print, and why?
a = 7
def my_value(b) a = b end
my_value(a + 5)
puts a
= 7
a inside of my_value is not available outside the method and (a) top level is not available inside my_value. Furthermore; a = b is assignment and now points to a new object.
Methods are self contained with respect to local variables.
What will the following code print, and why?
a = “Xyzzy”
def my_value(b)
b[2] = ‘-‘
end
my_value(a)
puts a
=> Xy-zy”
b[2] = is a method that mutates the caller, thus whats mutated inside of the method affects the object the top level variable points to.
Strings are mutable, numbers are not. Since we are actually modifying the string referenced by b, and b references the same string as a, the result from printing a shows an update to the value of the string.
What will the following code print, and why?
a = “Xyzzy”
def my_value(b) b = 'yzzyX' end
my_value(a)
puts a
=> ‘Xyzzy’
nothing happens, b inside the method is assigning b to a new object, a is still pointing to the original object. Assignment does not mutate. Inside variables are not available outside.
Assignment never changes the value of an object; instead, it creates a new object, and then stores a reference to that object in the variable on the left.
What will the following code print, and why?
a = 7
def my_value(b) b = a + a end
my_value(a)
puts a
=> Error message. Variable a inside method is not defined (assigned).
Even though a is defined before my_value is defined, it is not visible inside my_value. Methods are self contained with respect to local variables; local variables defined inside the method are not visible outside the method, and local variables defined outside the method are not visible inside the method.
What will the following code print, and why?
a = 7 array = [1, 2, 3]
array.each do |element|
a = element
end
puts a
=> 3
Variables at top level are available inside of blocks like the each method. a = element is reassignment of a. a is iterated through each item in the array and assigned to each item in sequence 1, 2, 3 so by the time puts is called on a it is equal to 3.
In this case, a starts out as 7, then we set a to 1, 2 and 3 in sequence. By the time we get to the puts, a has a value of 3.