What Is Local Scope Exactly

what is local scope exactly?

A local variable is used "right here right now" and can't be accessed from anywhere else.

class MyClass
def foo
local_var = 2
#I use this to do some sort of calculation
@instance_var = local_var + 34
local_var = 5 * @instance_var
puts local_var
end
# From here, local_var is unaccessible.
end

Once you're out of scope (foo's end is passed) local_var is no more and can't be referred to.

The instance variable is available to the whole class at all times.

class MyClass
def initialize
@instance_var = 0
end

def foo
local_var = 2
#I use this to do some sort of calculation
@instance_var = local_var + 34
end

def some_operation
if @instance_var == 36
@instance_var = 3
else
@instance_var = 1
end
end
end

So when you call m = MyClass.new and later on m.some_operation, it's working with the same @instance_var .

And while we're at it, there are also Class variables (defined @@class_var) that are accessible from any instance of the class.

I don't have an article in particular to provide you, but some googling about ruby variable scope and about each type of variable independently should provide you with all the information you need!

What is the scope of variables in JavaScript?

TLDR

JavaScript has lexical (also called static) scoping and closures. This means you can tell the scope of an identifier by looking at the source code.

The four scopes are:

  1. Global - visible by everything
  2. Function - visible within a function (and its sub-functions and blocks)
  3. Block - visible within a block (and its sub-blocks)
  4. Module - visible within a module

Outside of the special cases of global and module scope, variables are declared using var (function scope), let (block scope), and const (block scope). Most other forms of identifier declaration have block scope in strict mode.

Overview

Scope is the region of the codebase over which an identifier is valid.

A lexical environment is a mapping between identifier names and the values associated with them.

Scope is formed of a linked nesting of lexical environments, with each level in the nesting corresponding to a lexical environment of an ancestor execution context.

These linked lexical environments form a scope "chain". Identifier resolution is the process of searching along this chain for a matching identifier.

Identifier resolution only occurs in one direction: outwards. In this way, outer lexical environments cannot "see" into inner lexical environments.

There are three pertinent factors in deciding the scope of an identifier in JavaScript:

  1. How an identifier was declared
  2. Where an identifier was declared
  3. Whether you are in strict mode or non-strict mode

Some of the ways identifiers can be declared:

  1. var, let and const
  2. Function parameters
  3. Catch block parameter
  4. Function declarations
  5. Named function expressions
  6. Implicitly defined properties on the global object (i.e., missing out var in non-strict mode)
  7. import statements
  8. eval

Some of the locations identifiers can be declared:

  1. Global context
  2. Function body
  3. Ordinary block
  4. The top of a control structure (e.g., loop, if, while, etc.)
  5. Control structure body
  6. Modules

Declaration Styles

var

Identifiers declared using var have function scope, apart from when they are declared directly in the global context, in which case they are added as properties on the global object and have global scope. There are separate rules for their use in eval functions.

let and const

Identifiers declared using let and const have block scope, apart from when they are declared directly in the global context, in which case they have global scope.

Note: let, const and var are all hoisted. This means that their logical position of definition is the top of their enclosing scope (block or function). However, variables declared using let and const cannot be read or assigned to until control has passed the point of declaration in the source code. The interim period is known as the temporal dead zone.

function f() {
function g() {
console.log(x)
}
let x = 1
g()
}
f() // 1 because x is hoisted even though declared with `let`!

Block scope, function scope and local scope in Javascript

I'm not sure you really got your questions answered yet:

Is block scope sometimes the same as function scope? I know function scope is for everything inside a function, but don't get what
exactly a block scope is.

Yes, a block scope is sometimes the same as a function scope. Block scope is everything inside a set of braces { a block scope here }. So, at the top of a function's code, a block scope will be the same as a function scope:

function test(x) {
// this is both a block scope and a function scope
let y = 5;
if (x) {
// this is a smaller block scope that is not the same as the function scope
let z = 1;
}
}

For Javascript, is it currently recommended to use let / const instead
of var for future maintenance? (This was from Airbnb Style Guide)

let and const are part of the newest ES6 specification and are only implemented in the latest Javascript engines and sometimes in the latest engines they are only enabled with special flags. They are coming to all newer JS engines/browsers, but are not widely deployed yet. Thus, if you are writing Javascript for regular browser consumption across the broad internet, you cannot reliably use let and const yet.

There are some cases where you can safely program with let and const now:

  1. If you are targeting only a specific Javascript engine and you know that it has support for those features (such as a specific version of nodejs or a plug-in only for a specific version of a specific browser).

  2. If you are using a transpiler that will convert your code to code that will run in all browsers. When using a transpiler, you can write your code using the latest features and the transpiler will "dumb it down" so that your code will work in older browsers by using simulations of the newer features.

If you are programming for an environment where you know that let and const are supported, then it is advisable to use them as appropriate. If you declare a variable at the top of your function, then let and var will do the same thing.

If you declare a variable in a smaller scope within the function, then let will be contained within the smaller scope, but var will be hoisted to the top of the function and will have function scope, no matter where it is declared.


The AirBnb Style Guide you linked to is specifically written for an ES6 environment (note there is a separate link for an ES5 version of their style guide). So, that means that they are assuming an ES6 capable environment. That's either because they are targeting a server-side JS engine that they know supports ES6 or because they are using a transpiler that will convert ES6 code into something that will run on an ES5 engine.


A note about transpilers. Before using a transpiler and switching all variable declarations to let within block scopes, it is worth understanding what kind of code the transpiler generates and whether the extra code it generates has any effect on the performance of your application. For example, block scope for let is simulated by creating an inline IIFE which can lead to extra run-time overhead for every block that contains a let statement. I'm not saying this is necessarily a bad thing that should keep you from using a transpiler, but when deciding whether to use a transpiler, I'd suggest that you thoroughly familiarize yourself with what the transpiled code looks like for a variety of ES6 features so you know whether it is the right tool for any job you have or only for some jobs.

Coldfusion local scope outside of a function?

The Local scope is only defined within functions and should not be used outside of it.

Variables defined outside the functions, default to the variables scope.

//that way
myVar = 0;
//will be the same as
variables.myVar = 0;

When you refer to local.madVar2 variable, which was initialized outside the function you're essentially referring to the local.madVar2 in the variables scope i.e the variable madVar2 is stored inside a struct named local which is stored in the variables scope.

So essentially, with the proper scoping in place your code is treated as:

writeOutput("variables.local.madVar2: <BR>");     
writeDump(variables.local.madVar2);

Try dumping the variables scope just after defining the variables inside the function as:

var madVar = "madness variable";
madVar2 = "madness two variable";
writeDump(variables);
.....

You will see how the variables fall into scopes.

Sample Image

What the C++ standard exactly means by same scope in [basic.scope.hiding]?

what are the cases where the class C and the variable C are declared in the same scope?

Cases 1 and 4 are the same scope. Cases 2 and 3 are not the same scope.

I cannot indeed find an accurate definition in the standard for "same" in this context, but the interpretation that makes sense, and matches the results of your test is to compare the smallest enclosing scope (or rather, declarative region1) of each declaration.

Hypothesis 1: "same scope" means "same block"

While a block has a scope, they are not equivalent. There are also namespace scopes and class scopes for example.

but can't explain the case 4. Indeed, C enumerator is declared in a different block than C class but the class is still hided.

Enumeration declarations don't have a scope. The enumerator and the class are in the same scope.

Hypothesis 2: "declared in the same scope" means "have exactly the same scope"

As you say, no declaration can have exactly the same scope with another, so this interpretation would make the rule meaningless.

Hypothesis 3: "declared in the same scope" means "one of the name is declared inside the scope of the other"

This is not correct interpretation in that a nested scope can be within the scope of one declaration, but it is not the same scope as far as the rule in question is concerned.


1 In the latest standard draft, the wording has been changed to use the term "declarative region", which apparently has subtly different meaning than "scope". It doesn't change the intended meaning of the rule though.

What is lexical scope?

I understand them through examples. :)

First, lexical scope (also called static scope), in C-like syntax:

void fun()
{
int x = 5;

void fun2()
{
printf("%d", x);
}
}

Every inner level can access its outer levels.

There is another way, called dynamic scope used by the first implementation of Lisp, again in a C-like syntax:

void fun()
{
printf("%d", x);
}

void dummy1()
{
int x = 5;

fun();
}

void dummy2()
{
int x = 10;

fun();
}

Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.

dummy1();

will print 5,

dummy2();

will print 10.

The first one is called static because it can be deduced at compile-time, and the second is called dynamic because the outer scope is dynamic and depends on the chain call of the functions.

I find static scoping easier for the eye. Most languages went this way eventually, even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function.

As an example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example. If we write something like this:

if(/* some condition */)
dummy1();
else
dummy2();

The call chain depends on a run time condition. If it is true, then the call chain looks like:

dummy1 --> fun()

If the condition is false:

dummy2 --> fun()

The outer scope of fun in both cases is the caller plus the caller of the caller and so on.

Just to mention that the C language does not allow nested functions nor dynamic scoping.

In Lua, is there a difference between local functions declared with and without the local keyword?

function a() end in your code block assigns global a when the function is ran*, while b remains local to the function.

Perhaps this code segment will illustrate things better:

function f()
function a() end
local function b() end
end
print(a, b) -- nil, nil
f()
print(a, b) -- function: 0xdeadbeef, nil

So to avoid polluting the global environment, you should still use local inside of a function.


* Unless you declared a local at some other scope above f, in which case a will keep its scoping.

What does exactly nonlocal keyword do with a variable?

locals() is a very weird function that doesn't do what anyone would reasonably expect it to, with some bizarre undocumented quirks. This particular quirk happens to be documented, but it's still really weird. Generally, you shouldn't use locals() unless you really have no other choice.

The dict returned by locals() is

  • usually not the actual local variable namespace, and
  • may contain variables that aren't actually part of the current local variable namespace.

When called inside a function, the dict returned by locals() will include nonlocal variables:

Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

That doesn't mean the variable actually exists in multiple namespaces at the same time. It means locals() is weird.


As for the ID change, IDs are associated with objects, not variables. The integer object var1 refers to after var1 += 1 is a different object with a different ID than the previous integer object.

Scope vs life of variable in C

Scope is the region where the variable is accessible.

Life time is the time span during which an object remains valid.

An simple example:

#include <iostream.h>

void doSomething()
{
x = 5; //Error! Not Accessible
}

int main()
{

int x = 4;
std::cout<< x << endl;
{
int x = 2;
cout << x << endl;
}
doSomething();
std::cout<< x << endl;
return 0;
}

The above gives the output:

4

2

4

In above program,

lifetime of variable x = 4 is throughout the main, i.e: It remains alive throughout the execution of the main, Also it is accessible within the main, that is its scope. Note that it is not accessible in the function because it is beyond the scope of the variable x.

while scope and lifetime of variable x = 2 is within the enclsing braces{ } inside the main.



Related Topics



Leave a reply



Submit