Skip to main content
replaced http://programmers.stackexchange.com/ with https://softwareengineering.stackexchange.com/
Source Link

(Note that while http://programmers.stackexchange.com/q/42941/How do you navigate and refactor code written in a dynamic language? has a similar title to this question, it is wholly unrelated.)

(Note that while http://programmers.stackexchange.com/q/42941/ has a similar title to this question, it is wholly unrelated.)

(Note that while How do you navigate and refactor code written in a dynamic language? has a similar title to this question, it is wholly unrelated.)

clarify examples
Source Link
senshin
  • 334
  • 1
  • 11
function foo() { print(x); // not defined locally => uses whatever value `x` has in the calling context y = "tetanus"; } function bar() { var x = "measles"; foo(); print(y); // not defined locally, but set by the call to `foo()` } bar(); // prints "measles" followed by "tetanus" 

That is, variables propagate up and down the call stack freely - all variables defined in foo are visible to (and mutatable by) its caller bar, and the reverse is also true. This has serious implications for code refactorability. Imagine that you have the following code:

function a() { // defined in file A var x = "qux"; b(); } function b() { // defined in file B c(); } function c() { // defined in file C print(x); } 

Now, calls to a() will print qux. But then, someday, you decide that you need to change b() a little bit. You don't know all the calling contexts (some of which may in fact be outside your codebase), but that should be alright - your changes are going to be completely internal to b, right? So you rewrite it like this:

function b() { var x = "oops"; c(); } 

There are some obvious good practices for making refactoring easier, like never using variables in a function other than those you initialize (NEW) yourself or are passed as an explicit parameter, and explicitly documenting any parameters that areare implicitly passed from a function's callers. But in a decades-old, ~108-LOC codebase, these are luxuries one often does not have.

function foo() { print(x); y = "tetanus"; } function bar() { var x = "measles"; foo(); print(y); } bar(); // prints "measles" followed by "tetanus" 

This has serious implications for code refactorability. Imagine that you have the following code:

function a() { // defined in file A var x = "qux"; b(); } function b() { // defined in file B c(); } function c() { // defined in file C print(x); } 

Now, calls to a() will print qux. But then, someday, you decide that you need to change b() a little bit. You don't know all the calling contexts (some of which may in fact be outside your codebase), but that should be alright - your changes are going to be completely internal to b, right? So you rewrite it like this:

function b() { var x = "oops"; c(); } 

There are some obvious good practices for making refactoring easier, like never using variables in a function other than those you initialize (NEW) yourself or are passed as an explicit parameter, and explicitly documenting any parameters that are implicitly passed from a function's callers. But in a decades-old, ~108-LOC codebase, these are luxuries one often does not have.

function foo() { print(x); // not defined locally => uses whatever value `x` has in the calling context y = "tetanus"; } function bar() { x = "measles"; foo(); print(y); // not defined locally, but set by the call to `foo()` } bar(); // prints "measles" followed by "tetanus" 

That is, variables propagate up and down the call stack freely - all variables defined in foo are visible to (and mutatable by) its caller bar, and the reverse is also true. This has serious implications for code refactorability. Imagine that you have the following code:

function a() { // defined in file A x = "qux"; b(); } function b() { // defined in file B c(); } function c() { // defined in file C print(x); } 

Now, calls to a() will print qux. But then, someday, you decide that you need to change b a little bit. You don't know all the calling contexts (some of which may in fact be outside your codebase), but that should be alright - your changes are going to be completely internal to b, right? So you rewrite it like this:

function b() { x = "oops"; c(); } 

There are some obvious good practices for making refactoring easier, like never using variables in a function other than those you initialize (NEW) yourself or are passed as an explicit parameter, and explicitly documenting any parameters that are implicitly passed from a function's callers. But in a decades-old, ~108-LOC codebase, these are luxuries one often does not have.

Tweeted twitter.com/#!/StackProgrammer/status/642761370488958976
fix example code
Source Link
senshin
  • 334
  • 1
  • 11
function b() { var x = "oops"; print(x); c(); } 
function b() { var x = "oops"; print(x); c(); } 
function b() { var x = "oops"; c(); } 
words
Source Link
senshin
  • 334
  • 1
  • 11
Loading
Source Link
senshin
  • 334
  • 1
  • 11
Loading