Lab: Scope and Ruby
In today's lab, you'll explore dynamic and static scoping and solve a Ruby coding challenge that hits on namespaces and hashes.
Scoping
Consider the following program in a C-like language that allows nested procedures:
void main() {
int z = 10;
void g() {
int x = 12;
int y = 3; // line A
void f() {
z = x * y;
printLine(x, y, z); // line B
}
void h() {
int y = 2;
int z = 5; // line C
x = y + z;
printLine(x, y, z)
f();
}
h();
printLine(x, y, z);
}
g(); // line D
}
Answer the following questions. Recall that a variable is in scope under static scoping if you can find a prior declaration either in the current block or in the surrounding blocks. The nesting and sequencing of the code itself is what matters. A variable is in scope under dynamic scoping if you can walk through the stack frames and find the variable. The call sequence is what matters—not the code structure.
-
If this language has static scoping, what is the environment that is in scope immediately after line A? List only the variables that are visible, and qualify them by their owner. For example, if a function sees the
z
variable inh
, writeh::z
. - After line B?
- After line C?
- After line D?
- What is the output of this program if the language has static scoping?
- If this language has dynamic scoping, what is the environment that is in scope after line A?
- After line B?
- After line C?
- After line D?
- What is the output of this program if the language has dynamic scoping?
Tag
Write two Ruby source files: html.rb
and main.rb
. You are encouraged to place the code you write for lab in your official GitHub repository for this course—in a folder separate from your project.
In html.rb
, define a module named Html
with a function named make_tag
. Make it static using self
. Have it accept these three parameters:
- an element name
- a hash of attributes
-
a symbol that is one of
:empty
,:sandwich
, or:selfclose
It returns an HTML tag as a string. Form the string as demonstrated in these example calls:
-
make_tag('img', {src: 'bernie.jpg'}, :empty)
→'<img src="bernie.jpg">'
-
make_tag('div', {id: 'root', class: 'frame'}, :sandwich)
→'<div id="root" class="frame"></div>'
-
make_tag('Gallery', {}, :selfclose)
→'<Gallery />'
In main.rb
, include your module file with require_relative
, call your function several times to test it, and print the resulting tag each time. Ensure that your solution works for any tag, attribute hash, and tag format—and not just the examples.
Do not use include
or extends
or any other command for importing Ruby modules that you might read about on the web. Modules are used to achieve several different ends in Ruby. The include
and extends
commands are ways of making a class inherit code from a module, which is not what you want. All you want is to call a method defined in a namespace.
Submit
To receive credit for this lab, you must submit your two Ruby source files and a digital version of your answers to the scoping problems on Canvas by Monday noon. Late labs or forgot-to-submits are not accepted because Monday at noon is when your instructor has time to grade.