• No se han encontrado resultados

ÁREA DE INFRAESTRUCTURA: 1.- Laboratorio de Tumbes

RESUMEN EJECUTIVO DE LOS PRINCIPALES LOGROS

ÁREA DE INFRAESTRUCTURA: 1.- Laboratorio de Tumbes

Up to now, the governing principle was "all or nothing": either all variables of a function or a script were private or they were public (global). Now, let's use the scope modifiers private, local, script, and global.

Scope

allocation Description

$private:tes t = 1

The variable will be created only in the current scope and not passed to other scopes. Consequently, it can only be read and written in the current scope.

$local:test = 1

Variables will be created only in the local scope. That is the default for variables that are specified without a scope. Local variables can be read from scopes originating from the current scope, but they cannot be modified.

$script:test = 1

The variable is valid only in a script, but valid everywhere in it. Consequently, a function in a script can address other variables, which, while defined in a script, are outside the function.

$global:test

= 1 The variable is valid everywhere, even outside functions and scripts.

Table 3.3: Variable scopes and validity of variables

PowerShell automatically creates scopes, even when you first start the PowerShell console. It gets the first (global) scope. Additional scopes will be added when you use functions and scripts. Every function and every script acquires its own scope. As long as you work from within the PowerShell console, there will be only one scope. In this case, all scope allocations will function in exactly the same way:

$test = 1 $local:test 1 $script:test = 12 $global:test 12 $private:test 12

Create a second scope by defining a function. As soon as you call the function, PowerShell will switch to the function's own new scope. And now things appear somewhat confusing: which rules apply to variables and their validity? Let's take a look at what happens to variables that you create in the scope of the console and then read or modify in the scope of the function:

# Define test function:

Function test { "variable = $a"; $a = 1000 }

# Create variable in console scope and call test function:

$a = 12 Test

variable = 12

# After calling test function, control modifications in console scope:

$a 12

When you don't use any special scope allocators, a new scope can read the variables of the old scope, but not change them. If the new scope modifies a variable from the old scope, as in the example above, then the modification will be automatically created in a new local variable of the new scope. The modification has no effect on the old scope.

Is it possible to prevent variables from the old scope from being read by a new scope? The answer is yes. Variables are private for the allocator, since the variables that you create with it are not passed to other scopes. The function then reports "variable = ", because the variable $a is suddenly

invisible to the function.

# Define test function:

Function test { "variable = $a"; $a = 1000 }

# Create variable in console scope and call test function:

$private:a = 12 Test

variable =

$a 12

Only when you create a completely new variable by using $private: is it in fact private. If the variable already existed, PowerShell will not reset the scope of the existing variable. That is (somewhat) logical, because there is only one scope in the console scope. The existing variable is found under the private: allocator and so is not created again.

To achieve the result you expect, you must either first remove the existing variable $a using the statement Remove-Variable a before you create it again, or manually allocate the status of a private variable to an existing variable: (Get-Variable a).Options = "Private". Also, by using (Get-Variable

a).Options = "None" you can make a variable become a local variable again.

The scope of a variable is disclosed, as shown in Table 3.6, by selecting the

Options property.

It works conversely too as the function can also modify the variable in the console scope. That's the purpose of the global: allocator. If it's specified, then the statement changes the variable in all existing scopes:

# Define test function:

Function test { "variable = $a"; $global:a = 1000 }

# Create variable in console scope and call test function:

Remove-Variable a

$private:a = 12 Test

variable =

# After calling test function check variable for modifications # in console:

$a 1000

The allocator script: works in a very similar way. It makes a variable global inside of a script, but does not touch variables outside of the script. If you call the function directly from within the console, then global: and script: will supply the same result. But when you use script: from within PowerShell scripts, you will create variables that are valid everywhere within the script. However, after termination of the script, will have no effect on the console used to call the script.

Scope Use

function ends its work.

$script The variable is valid only within a script, but everywhere within it. Once the script is executed, the variable is removed.

$private The variable is valid only in the current scope, either a script or a

function. It cannot be passed to other scopes.

$local

The variable is valid only in the current scope. All scopes called with it can read, but not change, the contents of the variable.

Modifications are also stored in new local variables of the current scope. $local: is the default if you don't specify a particular scope.

Table 3.4: Practical usage of scope allocations

Variable Types and "Strongly Typing"

Variables store arbitrary information when PowerShell automatically picks the appropriate data type. You don't have to do anything. However, by appending the command .GetType().Name to a

variable, you can verify the data type that PowerShell has chosen for a variable. You don't even need the variable. Type the value in parentheses and call .GetType().Name to find out in which data type PowerShell stores the value:

(12).GetType().Name Int32 (1000000000000).GetType().Name Int64 (12.5).GetType().Name Double (12d).GetType().Name Decimal ("H").GetType().Name String

DateTime

PowerShell assigns the best-fit primitive data type for a given value. If a number is too large for a 32-bit integer, it will use a 64-bit integer. If it's a decimal number, then the Double data type will be used. In the case of text, PowerShell uses the String data type. Date and time values are stored in

DateTime objects.

This process of automatic selection is called "weakly typed," and while easy, it's also often restrictive —or even risky. If PowerShell picks the wrong data type, strange things can happen. For example, let's say a variable should really store the number of files to be copied. If you erroneously assign a text value instead of a numeric value to this variable, PowerShell will happily store the text, not the number. The variable type will be automatically modified. This is why professional programmers and script developers often prefer strongly typed variables that specify the exact type of data to be stored, rather than delivering error messages when a wrong data type is assigned.

Another reason for a strong type specification: Every data type has its own set of helper functions. In fact, PowerShell doesn't always select the best data type for a particular value. For example, date, time and XML, are by default stored as plain text in a String data type. This is somewhat unfortunate, because you'll have to do without many useful date or XML commands that use

specialized DateTime or XML data types. So, in practice, there are two important reasons for you to set the variable type yourself:

Type safety: If you have assigned a type to a variable yourself, then the type will be preserved no matter what happens and will never be automatically modified. You can be

absolutely sure that a value of the correct type is stored in the variable. If later on someone

were to mistakenly assign a value to the variable that doesn't match the originally chosen type, this will cause an error message to be delivered.

Special variable types: When automatically assigning a variable type, PowerShell takes into consideration only general variable types like Int32 or String. Often, it's appropriate to store values in a specialized variable type like DateTime in order to be able to use the special commands and options available for this variable type.