Scope modifiers: Difference between revisions

From Rosetta Code
Content added Content deleted
m (Added static scoping a.k.a.)
(Add Python 3.x)
Line 74: Line 74:
//can use x and y here, but NOT z
//can use x and y here, but NOT z
}</lang>
}</lang>


=={{header|Python}}==
Python from version 3 has the global and nonlocal access modifiers:
* <code>global</code> instructs the interpreter to search for the name(s) in the outermost sccope.
* <code>nonlocal</code> instructs the interpreter to search for the name(s) starting from the innermost enclosing scope going outwards.
Without either keyword, a reference to a name must have the name defined in the current scope or if not, then it is looked for in the global scope - skipping any intermediate scopes.

In the example below the name <code>x</code> is defined at various scopes and given a different value dependent on its scope. The innermost functions demonstrate how the scope modifiers give acccess to the name from different scopes:

<lang python>>>> x="From global scope"
>>> def outerfunc():
x = "From scope at outerfunc"

def scoped_local():
x = "scope local"
return "scoped_local scope gives x = " + x
print(scoped_local())

def scoped_nonlocal():
nonlocal x
return "scoped_nonlocal scope gives x = " + x
print(scoped_nonlocal())

def scoped_global():
global x
return "scoped_global scope gives x = " + x
print(scoped_global())

def scoped_notdefinedlocally():
return "scoped_notdefinedlocally scope gives x = " + x
print(scoped_notdefinedlocally())

>>> outerfunc()
scoped_local scope gives x = scope local
scoped_nonlocal scope gives x = From scope at outerfunc
scoped_global scope gives x = From global scope
scoped_notdefinedlocally scope gives x = From global scope
>>> </lang>
More information on the scope modifiers can be found [http://docs.python.org/3.0/reference/simple_stmts.html#grammar-token-global_stmt here].<br>

Revision as of 20:21, 10 June 2009

Task
Scope modifiers
You are encouraged to solve this task according to the task description, using any language you may know.

Most programming languages offer support for subroutines. When execution changes between subroutines, different sets of variables and functions ("scopes") are available to the program. Frequently these sets are defined by the placement of the variable and function declarations ("static scoping" or "lexical scoping"). These sets may also be defined by special modifiers to the variable and function declarations.

Show the different scope modifiers available in your language and briefly explain how they change the scope of their variable or function. If your language has no scope modifiers, note it.

Ada

Public and private declarative parts

In Ada declarative region of a package has publicly visible and private parts. The private part is introduced by private: <lang ada> package P is

  ... -- Declarations placed here are publicly visible

private

  ... -- These declarations are visible only to the children of P

end P; </lang> Correspondingly a type or object declaration may be incomplete in the public part providing an official interface. For example: <lang ada> package P is

  type T is private; -- No components visible
  procedure F (X : in out T); -- The only visible operation
  N : constant T; -- A constant, which value is hidden

private

  type T is record -- The implementation, visible to children only
     Component : Integer;
  end record;
  procedure V (X : in out T); -- Operation used only by children
  N : constant T := (Component => 0); -- Constant implementation

end P; </lang>

Bodies (invisible declarations)

The keyword body applied to the packages, protected objects and tasks. It specifies an implementation of the corresponding entity invisible from anywhere else: <lang ada> package body P is

  -- The implementation of P, invisible to anybody
  procedure W (X : in out T); -- Operation used only internally

end P; </lang>

Private children

The keyword private can be applied to the whole package, a child of another package: <lang ada> private package P.Q is

  ... -- Visible to the siblings only

private

  ... -- Visible to the children only

end P.Q; </lang> This package can be then used only by private siblings of the same parent P.

Java

<lang java>public //any class may access this member directly

protected //only this class, subclasses of this class, //and classes in the same package may access this member directly

private //only this class may access this member directly

static //for use with other modifiers //limits this member to one reference for the entire JVM

//adding no modifier allows access to the member by classes in the same package

//method parameters are available inside the entire method

//Other declarations follow lexical scoping, //being in the scope of the innermost set of braces ({}) to it. //You may also create local scopes by surrounding blocks of code with braces.

public void function(int x){

  //can use x here
  int y;
  //can use x and y here
  {
     int z;
     //can use x, y, and z here
  }
  //can use x and y here, but NOT z

}</lang>


Python

Python from version 3 has the global and nonlocal access modifiers:

  • global instructs the interpreter to search for the name(s) in the outermost sccope.
  • nonlocal instructs the interpreter to search for the name(s) starting from the innermost enclosing scope going outwards.

Without either keyword, a reference to a name must have the name defined in the current scope or if not, then it is looked for in the global scope - skipping any intermediate scopes.

In the example below the name x is defined at various scopes and given a different value dependent on its scope. The innermost functions demonstrate how the scope modifiers give acccess to the name from different scopes:

<lang python>>>> x="From global scope" >>> def outerfunc():

   x = "From scope at outerfunc"
   def scoped_local():
       x = "scope local"
       return "scoped_local scope gives x = " + x
   print(scoped_local())
   def scoped_nonlocal():
       nonlocal x
       return "scoped_nonlocal scope gives x = " + x
   print(scoped_nonlocal())
   def scoped_global():
       global x
       return "scoped_global scope gives x = " + x
   print(scoped_global())
   def scoped_notdefinedlocally():
       return "scoped_notdefinedlocally scope gives x = " + x
   print(scoped_notdefinedlocally())


>>> outerfunc() scoped_local scope gives x = scope local scoped_nonlocal scope gives x = From scope at outerfunc scoped_global scope gives x = From global scope scoped_notdefinedlocally scope gives x = From global scope >>> </lang> More information on the scope modifiers can be found here.