• Shuffle
    Toggle On
    Toggle Off
  • Alphabetize
    Toggle On
    Toggle Off
  • Front First
    Toggle On
    Toggle Off
  • Both Sides
    Toggle On
    Toggle Off
  • Read
    Toggle On
    Toggle Off
Reading...
Front

Card Range To Study

through

image

Play button

image

Play button

image

Progress

1/11

Click to flip

Use LEFT and RIGHT arrow keys to navigate between flashcards;

Use UP and DOWN arrow keys to flip the card;

H to show hint;

A reads text to speech;

11 Cards in this Set

  • Front
  • Back

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



This problem is identical to the previous problem. The only thing we did is change the name b to a. Note that we can do this because methods are self-contained with respect to local variables. 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.




Note - The exceptions are things that mutate the caller

What will the following code print, and why?




a = 7
def my_value(b)


a = b


end


my_value(a + 5)


puts a

7


Once again, the result is 7. Once again, a inside the my_value is not visible outside my_value, and a at the top level is not visible inside my_value because 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

This problem looks remarkably similar to the first problem in this set. However, this time we are working with a string, and we are assigning to b[2] instead of b.The result is quite different. When we were working with a numeric variable, no changes were made to a. This was due to the fact that numbers are immutable, and assignment merely changes the object that a variable references. Now, though, Strings are mutable - they can be modified - and, in particular, the method String#[]= is a mutating method; it actually modifies the string. 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.


Documentation

str[index] → new_str or nil

str[start, length] → new_str or nil

str[range] → new_str or nil

str[regexp] → new_str or nil

str[regexp, capture] → new_str or nil

str[match_str] → new_str or nil

What will the following code print, and why?

a = "Xyzzy"

def my_value(b)

b = 'yzzyX'

end


my_value(a)

puts a

Xyzzy

This problem is nearly identical to the previous problem, except this time we are assigning directly to the variable b. When my_value begins executing, b is set to reference the same string that is reference by a. If we modify that string by using b, then that modification is reflected in a; it's the same string.


However, we are not modifying that string in this exercise. Instead, we are assigning a completely new string to b. 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. So, at the end of my_value, b references the string 'yzzyX', while a remains unchanged: it still references "Xyzzy".


So, how does this differ from b[2] = '-'? The key difference with b[2] = '-' is that this is not quite the same as object assignment; it is a call to a method named []=, and this method updates the String referenced by b; it does not change the reference, so a is also referencing the modified String.


To summarize, assignment to a variable (an object) never mutates the object that is referenced. However, don't take that too far: if you assign to b[2] like we did in the previous exercise, that's a completely different operation; that actually mutates the content of the String referenced by b.

What will the following code print, and why?


a = 7


def my_value(b)

b = a + a

end

my_value(a)
puts a

`my_value': undefined local variable or method `a' for main:Object (NameError)


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.Note, however, that local variables will be visible (via closures) inside blocks, procs, and lambdas.

What will the following code print, and why?



a = 7


array = [1, 2, 3]




array.each do |element|


a = element


end




puts a

3

We are now dealing with blocks; the rules for blocks differ from the rules for methods. In methods, local variables are self-contained. Not so in blocks; blocks can use and modify local variables that are defined outside the block.


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.

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)


Compared to the previous exercise, all we have done is remove the assignment of the a at the top level to after the block, and that has a completely different result. We now get an exception when the puts is executed because a is not defined. It is undefined because a in the block is local to the block; it is local to the block because a was not previously defined prior to the block.

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 method `+' for nil:NilClass (NoMethodError)


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.

Modify the code below so that the user's input gets added to the numbers array. Stop the loop when the array contains 5 numbers.



numbers = []loop do puts 'Enter any number:' input = gets.chomp.to_iendputs numbers

numbers = []loop do puts 'Enter any number:' input = gets.chomp.to_i numbers.push(input) break if numbers.size == 5endputs numbers






When dealing with user input, it's likely the input will either be evaluated or added to something. In this case, we're adding an integer to an array. Array#push works well for this because it will take the value of input and add it to the end of the numbersarray, which is exactly what we need.Now that we are handling the input properly, the next step is to stop the loop. We can accomplish this by taking advantage of the Array#size method. #size returns the number of elements contained in the caller. To stop the loop when numberscontains 5 elements, we can simply add a break with an if numbers.size == 5 condition.