Programming Foundations Flashcards

1
Q

Are variables accessible outside an ‘if condition’?

A

Yes, they are - since an ‘if condition’ does not create a block.

Variables created inside a block aren’t visible to the outer scope.

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

Where are Kernel methods available in Ruby?

A

Everywhere. The Kernel module is loaded by ‘Object’, giving us access to all of its methods.

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

Why can we omit the Kernel. in front of method names?

A
When we write Ruby code that's not in a class, we are working with an object called 'main', which is an instance of 'Object'. The 'Kernel' module is automatically loaded by 'Object
, giving us access to all of its methods.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What are some good guidelines on how to write good methods?

A
  • It shouldn’t display something to the output as well as return a value
  • Decide whether the method should return something with no side effects OR only perform side effects with no return. The naming should also reflect this.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What is ‘truthiness’ in Ruby?

A

Ruby is very liberal about what ‘true’ means.

In Ruby, everything is truthy except nil and false.

Because of this, we don’t have to compare an expression to ‘true’ or ‘false’, and can rely on the expression’s ‘truthiness’ directly.

Example:
if user_input == true

could be just

if user_input

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

What determines variable scoping?

A

Whether you’re working with blocks (a piece of {..} or do..end following a method invocation.

Example:
3.times do |n|
a = 3
end

Things like loops also have an inner scope. However, they can access outer scope variables and even make changes to them (for example, if you re-assign an outer scope variable in a loop, that change will persist in the outer scope!”

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

Can methods access outer scope variables?

A

No, they create their own variable scoping that’s entirely out of the execution flow.

The one exception to this is Constants. They tend to behave like global variables and can be accessed by methods and blocks.

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

What is variable shadowing?

A

Variable shadowing:

We’ve been using the loop do…end, which doesn’t take a parameter, but some blocks do take a parameter. Take for example:

[1, 2, 3].each do |n|
puts n
end

The block is the do…end, and the block parameter is captured between the | symbols. In the above example, the block parameter is n, which represents each element as the each method iterates through the array.

But what if we had a variable named n in the outer scope? We know that the inner scope has access to the outer scope, so we’d essentially have two local variables in the inner scope with the same name. When that happens, it’s called variable shadowing, and it prevents access to the outer scope local variable. See this example:

n = 10

[1, 2, 3].each do |n|
puts n
end
The puts n will use the block parameter n and disregard the outer scoped local variable. Variable shadowing also prevents us from making changes to the outer scoped n:

n = 10

1.times do |n|
n = 11
end

puts n # => 10

You want to avoid variable shadowing, as it’s almost never what you intended to do. Choosing long and descriptive variable names is one simple way to ensure that you don’t run into any of these weird scoping issues. And if you do run into these issues, you’ll have a much better chance of debugging it if you have clear variable names.

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

How do blocks and methods interface with each other?

A

Technically any method can be called with a block, but the block is only executed if the method is defined in a particular way.

A block is part of the method invocation; essentially the block acts as an argument to the method.

In the same way that a local variable can be passed as an argument to a method at invocation, when a method is called with a block it acts as an argument to that method.

Important to know is that, while methods can not access local variables initialized outside the method scope, blocks CAN do this. They can also reassign those variables!

Key takeaways about methods and blocks :
- The def..end construction in Ruby is method definition

  • Referencing a method name, either of an existing method or subsequent to definition, is method invocation
  • Method invocation followed by {..} or do..end defines a block; the block is part of the method invocation
  • Method definition sets a scope for local variables in terms of parameters and interaction with blocks
  • Method invocation uses the scope set by the method definition
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What does it mean when a method is mutating the caller?

A

This will affect the original object that is passed in.

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

Is Ruby pass by reference or pass by value?

A

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 modified. Objects passed to methods in this way are said to be passed by value, and the language is said to be using a pass by value object passing strategy.

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

Pass by value, as you’ll recall, means copying the original objects, so the original object cannot be modified. Since immutable objects cannot be changed, they act like Ruby passes them around by value. This isn’t a completely accurate interpretation of how Ruby passes immutable objects, but it helps us determine why the following code works like it does

So, is that our final answer to the question of whether ruby is pass by reference or pass by value? It’s neither? Yes. Well, maybe not entirely; there are actually three answers to the question of what object passing strategy ruby uses:

  • pass by reference value is probably the most accurate answer, but it’s a hard answer to swallow when learning ruby, and isn’t particularly helpful when trying to decide what will happen if a method modifies an argument – at least not until you fully understand it.
  • pass by reference is accurate so long as you account for assignment and immutability.
  • Ruby acts like pass by value for immutable objects, pass by reference for mutable objects is a reasonable answer when learning about ruby, so long as you keep in mind that ruby only appears to act like this.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How do mutable vs non-mutable objects get passed into Ruby methods?

A
def increment(a)
  a = a + 1
end
b = 3
puts increment(b)    # prints 4
puts b               # prints 3

Here, the numeric object 3 is immutable. You can reasonably say that b is not modified by #increment since b is passed by value to #increment where it is bound to variable a. Even though a is set to 4 inside the method, and returned to the caller, the original object referenced by b is untouched.

Mutable objects, on the other hand, can always be modified simply by calling one of their mutating methods. They act like Ruby passes them around by reference; it isn’t necessary for a method to modify an object that is passed by reference, only that it can modify the object. As you’ll recall, pass by reference means that only a reference 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 modify those objects. Once again, this isn’t completely accurate, but it is helpful.

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

Is indexed assignment mutating or non-mutating?

A

It’s mutating.

Indexed assignment, such as that used by String, Hash, and Array objects can be confusing:

str[3] = ‘x’

array[5] = Person.new

hash[:age] = 25

This looks exactly like assignment, which is non-mutating, but is, in fact, mutating. #[] modifies the original object (the String, Array, or Hash). It doesn’t change the binding of each variable.

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

What is Object Passing?

A

In ruby, nearly everything is an object. When you call a method with some expression as an argument, that expression is evaluated by ruby and reduced, ultimately, to an object.

The expression can be an object literal, an variable name, or a complex expression; regardless, it is reduced to an object. Ruby then makes that object available inside the method.

This is called passing the object to the method, or, more simply, object passing.

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

Why is Object Passing strategy important?

A

Most computer languages that employ strict evaluation use pass by value by default. Most of those languages also make it possible to pass by reference when needed.

Few languages are purely pass by value or pass by reference. Understanding which strategy is used (and when) is key to understanding what happens to an object that gets passed to a method.

For example, if the method does something that appears to change the object, is that change local to the method, or does it result in changes to the original object?

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

Describe the difference between ! and ? in Ruby.

A

Just to clarify, if you see ! or ? at the end of the method, it’s actually part of the method name, and not Ruby syntax. Therefore, you really don’t know what the method is doing, even if it ends in those characters – it depends on the method implementation.

17
Q

what is != and where should you use it?

A

!= means ‘not equals’, and is used in conditionals

18
Q

What does putting !! before a variable do?

A

It turns any object into their boolean equivalent

19
Q

What does putting ! before a variable do?

A

It turns any object into the opposite of their boolean equivalent.

20
Q

What 4 elements of a loop do selection and transformation definitely need?

A
Selection and transformation both utilize the basics of looping: 
a loop, 
a counter, 
a way to retrieve the current value, 
and a way to exit the loop. 

Keep those four things in mind. In addition, selection and transformation require some criteria; selection uses this criteria to determine which elements are selected, while transformation uses this criteria to determine how to perform the transformation.

21
Q

What’s the difference between .each and .map?

A

It’s all about their return value.

Both methods take a block as an argument, but what those methods do with the return value of that block is different.

.each will always return the original object it was called upon.

.map will use the return value of the block to perform transformation and put that result in a new collection.

If the return value of the block is true, it will perform some sort of transformation (if applicable) and place it in a new collection. This process is repeated for every element in the original object.
The original collection/ object also remains unchanged , unless the block uses a method that mutates the caller.

22
Q

What can you ask yourself when evaluating code? (5 points)

A

So what specific pieces of information are we interested in keeping track of? When evaluating code like this, ask the following questions:

1) What is the type of action being performed (method call, block, conditional, etc..)?
2) What is the object that action is being performed on?
3) What is the side-effect of that action (e.g. output or destructive action)?
4) What is the return value of that action?
5) Is the return value used by whatever instigated the action?