Lesson 2.20: Pass by Value vs. Pass by Reference Flashcards

1
Q

object

A

a bit of data that has some sort of state – sometimes called a value – and an associated behavior. It can be simple, like the boolean object true, or it can be complex, like an object that represents a database connection.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

object_id

A
Every object in Ruby has a unique object id, and that object id can be retrieved simply by calling `#object_id` on the object in question. Even literals, such as numbers, booleans, `nil`, and Strings have object ids:
>> 5.object_id
=> 11
>> true.object_id
=> 20
>> n
nil.object_id
=> 8
>> "abc".object_id
=> 70101471581080
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

setter method

A

(or simply, a setter) is a method defined by a Ruby object that allows a programmer to explicitly change the value of part of an object. Setters always use a name like something=

Ex.: Array#[]=

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Some languages make copies of method arguments, and pass those copies to the method — since they are merely copies, the original objects can’t be mutated. Objects passed to methods in this way are said to be ______, and the language is said to be using a ______ object passing strategy.

A

passed by value, pass by value

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Other languages pass _______ to the method instead — a _______ can be used to mutate the original object, provided that object is mutable. Objects passed to methods in this way are said to be _________, and the language is said to be using a ________ object passing strategy.

A

references; reference; passed by reference; pass by reference

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

_______, as you’ll recall, means copying the original objects, so the original object cannot be mutated. Since immutable objects cannot be changed, they act like Ruby ______________ .

A

Pass by value; passes them around by value

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Mutable objects, on the other hand, can always be mutated simply by calling one of their mutating methods. They act like Ruby passes them around by ________ ; it isn’t necessary for a method to mutate an object that is _____________, only that it can mutate the object. As you’ll recall, _________ means that only a _________ to an object is passed around; the variables used inside a method are bound to the original objects. This means that the method is free to mutate those objects. Once again, this isn’t completely accurate, but it is helpful.

A

reference; passed by reference; pass by reference; reference

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

The object that may or may not be mutated is of concern when discussing whether a method is mutating or non-mutating. For example, the method String#sub! is _______ with respect to the String used to call it, but _______ with respect to its arguments.

A

mutating; non-mutating

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

All methods are _______ with respect to immutable objects.

A

non-mutating

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
def fix(value)
  value.upcase!
  value.concat('!')
  value
end
s = 'hello'
t = fix(s)

When this code runs, what values do s and t have?

A

We start by passing s to fix; this binds the String represented by ‘hello’ to value. In addition, s and value are now aliases for the String.

Next, we call #upcase! which converts the String to uppercase. A new String is not created; the String that is referenced by both s and value now contains the value ‘HELLO’.

We then call #concat on value, which also mutates value instead of creating a new String; the String now has a value of “HELLO!”, and both s and value reference that object.

Finally, we return a reference to the String and store it in t.

The only place we create a new String in this code is when we assign ‘hello to s. The rest of the time, we operate directly on the object, mutating it as needed. Thus, both s and t reference the same String, and that String has the value ‘HELLO!’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
def fix(value)
  value = value.upcase
  value.concat('!')
end
s = 'hello'
t = fix(s)

Now what happens to the values of s and t?

A

In this modified code, we assign the return value of value.upcase back to value. Unlike #upcase!, #upcase doesn’t mutate the String referenced by value; instead, it creates a new copy of the String referenced by value, mutates the new copy, and then returns a reference to the copy. We then bind value to the returned reference. s and t now reference different objects, and the String referenced by s still references its original value.

>> def fix(value)
--   value = value.upcase
--   value.concat('!')
-- end
=> :fix
>> s = 'hello'
=> "hello"
>> s.object_id
=> 70349169469400
>> t = fix(s)
=> "HELLO!"
>> s
=> "hello"
>> t
=> "HELLO!"
>> s.object_id
=> 70349169469400
>> t.object_id
=> 70349169435840
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
def fix(value)
  puts "initial object #{value.object_id}"
  value = value.upcase
  puts "upcased object #{value.object_id}"
  value.concat('!')
end
s = 'hello'
puts "original object #{s.object_id}"
t = fix(s)
puts "final object #{t.object_id}"
If you run this code, you will see something like this:
original object 70349169469400
initial object 70349169469400
upcased object 70349169435840
final object 70349169435840
A

This shows that value = value.upcase bound the return value of value.upcase to value; value now references a different object than it did before. Prior to the assignment, value referenced the same String as referenced by s, but after the assignment, value references a completely new String; the String referenced by #upcase’s return value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Assignment ____ binds the target variable on the left hand side of the = to the object referenced by the right hand side. The object originally referenced by the target variable is _____ mutated.

A

always; never

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q
def fix(value)
  value << 'xyz'
  value = value.upcase
  value.concat('!')
end
s = 'hello'
t = fix(s)
A

This program mutates the original string so its value is helloxyz. However, thanks to the assignment on line 3, it is not mutated to HELLOXYZ or HELLOXYZ!; those mutations are made to the (different) object that the method returns.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
>> s = 'Hello'
=> "Hello"
>> s.object_id
=> 70101471465440
>> s += ' World'
=> "Hello World"
>> s
=> "Hello World"
>> s.object_id
=> 70101474966820
A

Though it looks as though we are mutating s when we write s += ‘ World’, we are actually creating a brand-new String with a new object id, then binding s to that new object.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q
str[3] = 'x'
array[5] = Person.new
hash[:age] = 25

This looks exactly like assignment, which is _______. However, in this case, it is ______. #[] _______ the original object (the String, Array, or Hash). It doesn’t change the ______ of each variable (str, array, hash).

A

non-mutating, mutating, mutates; binding

17
Q

indexed assignment

A
str[3] = 'x'
array[5] = Person.new
hash[:age] = 25
18
Q

+=

A

non-mutating

19
Q

<

A

mutating with respect to its caller.

The &laquo_space;operator is actually a method that is defined for some classes. It is usually used as a shorthand for appending new values to a collection or String. Such classes define &laquo_space;to mutate their left-hand operand (the caller).

20
Q

Every computer programming language uses some sort of ________ when passing objects. This strategy determines when expressions are evaluated, and what a method can do with the resulting objects. The most common strategies are known as __________ With _______, every expression is evaluated and converted to an object before it is passed along to a method. Ruby uses this exclusively.

A

evaluation strategy; strict evaluation strategies; strict evaluation

21
Q

The two most common strict evaluation strategies are _________ and ________. Collectively, we will refer to these as _________________________.

A

pass by value; pass by reference; object passing strategies

22
Q

To _____ a method or variable name in Ruby is to create a second name for the method or variable. _______ can be used either to provide more expressive options to the programmer using the class or to help override methods and change the behavior of the class or object. Ruby provides this functionality with the “____” and “__________” keywords.

A

alias; Aliasing; alias; alias_method

https://www.thoughtco.com/aliasing-in-ruby-2908190

23
Q
def plus(x, y)
  x = x + y
end
a = 3
b = plus(a, 2)
puts a # 3
puts b # 5
A

As you can see, although we assign a new value to x in #plus, the original argument, a, is left unchanged. (The method, however, does return the result of adding 2 to a, 5, which is stored in b.) So, you can say that ruby appears to be pass by value, at least with respect to immutable values.

24
Q
def uppercase(value)
  value.upcase!
end
name = 'William'
uppercase(name)
puts name               # WILLIAM
A

Here, our method can mutate the name String through the alias value, so it looks like ruby is pass by reference here.