Scope modifiers: Difference between revisions
Add Python 3.x |
→Tcl: Added implementation |
||
Line 115: | Line 115: | ||
>>> </lang> |
>>> </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> |
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> |
||
=={{header|Tcl}}== |
|||
In Tcl procedures, variables are local to the procedure unless explicitly declared otherwise (unless they contain namespace separators, which forces interpretation as namespace-scoped names). Declarations may be used to access variables in the global namespace, or the current namespace, or indeed any other namespace. |
|||
{{works with|Tcl|8.5}} |
|||
<lang tcl>set globalVar "This is a global variable" |
|||
namespace eval nsA { |
|||
variable varInA "This is a variable in nsA" |
|||
} |
|||
namespace eval nsB { |
|||
variable varInB "This is a variable in nsB" |
|||
proc showOff {varname} { |
|||
set localVar "This is a local variable" |
|||
global globalVar |
|||
variable varInB |
|||
namespace upvar ::nsA varInA varInA |
|||
puts "variable $varname holds \"[set $varname]\"" |
|||
} |
|||
} |
|||
nsB::showOff globalVar |
|||
nsB::showOff varInA |
|||
nsB::showOff varInB |
|||
nsB::showOff localVar</lang> |
|||
Output: |
|||
<pre>variable globalVar holds "This is a global variable" |
|||
variable varInA holds "This is a variable in nsA" |
|||
variable varInB holds "This is a variable in nsB" |
|||
variable localVar holds "This is a local variable"</pre> |
|||
Objects have an extra variable access mode. All the variables declared in a class definition are visible by default in the methods defined in that class. All other variable access modes are still available too. |
|||
{{works with|Tcl|8.6}} |
|||
<lang tcl>oo::class create example { |
|||
# Note that this is otherwise syntactically the same as a local variable |
|||
variable objVar |
|||
constructor {} { |
|||
set objVar "This is an object variable" |
|||
} |
|||
method showOff {} { |
|||
puts "variable objVar holds \"$objVar\"" |
|||
} |
|||
} |
|||
[example new] showOff</lang>Output:<pre>variable objVar holds "This is an object variable"</pre> |
Revision as of 20:43, 10 June 2009
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.
Tcl
In Tcl procedures, variables are local to the procedure unless explicitly declared otherwise (unless they contain namespace separators, which forces interpretation as namespace-scoped names). Declarations may be used to access variables in the global namespace, or the current namespace, or indeed any other namespace.
<lang tcl>set globalVar "This is a global variable" namespace eval nsA {
variable varInA "This is a variable in nsA"
} namespace eval nsB {
variable varInB "This is a variable in nsB" proc showOff {varname} { set localVar "This is a local variable" global globalVar variable varInB namespace upvar ::nsA varInA varInA puts "variable $varname holds \"[set $varname]\"" }
} nsB::showOff globalVar nsB::showOff varInA nsB::showOff varInB nsB::showOff localVar</lang> Output:
variable globalVar holds "This is a global variable" variable varInA holds "This is a variable in nsA" variable varInB holds "This is a variable in nsB" variable localVar holds "This is a local variable"
Objects have an extra variable access mode. All the variables declared in a class definition are visible by default in the methods defined in that class. All other variable access modes are still available too.
<lang tcl>oo::class create example {
# Note that this is otherwise syntactically the same as a local variable variable objVar constructor {} { set objVar "This is an object variable" } method showOff {} { puts "variable objVar holds \"$objVar\"" }
}
[example new] showOff</lang>Output:
variable objVar holds "This is an object variable"