0

Consider this:

SWITCH ($mode)
{
    MODE1
    {
    }

    MODE2
    {
    }

    MODE3
    {
    }
}

Can I directly call the code under MODE1, MODE2, or MODE3 without executing the entire SWITCH statement?

I have a situation where MODE3 can only run if MODE2 has been completed, and MODE2 can only run if MODE1 has been completed. I have moved all the code for each MODE into a separate function. However, the logic to determine if previous modes have completed is growing in size, duplicates code, and is confusing.

For instance:

SWITCH ($mode)
{
    MODE1
    {
         DoMode1
         if (!Mode1Complete) { Exit }
    }

    MODE2
    {
        if (!Mode1Complete) { DoMode1 }
        if (!Mode1Complete) { Exit }
        DoMode2
    }

    MODE3
    {
        if (!Mode2Complete)
        {
            if (!Mode1Complete)
            {
                DoMode1
                if (!Mode1Complete) { Exit }
                DoMode2
                if (!Mode2Complete) { Exit }
            }
            else
            {
                DoMode2
                if (!Mode2Complete) { Exit }
            }
        }
        DoMode3
    }
}

You can see how this will get complicated real quick!

What I want to do is this:

SWITCH ($mode)
{
    MODE1
    {
        DoMode1
        If (!Mode1Complete) { Exit }
    }

    MODE2
    {
        if (!Mode1Complete)
        {
            #Call MODE1
        }
        if (!Mode1Complete) { Exit }
        DoMode2
    }

    MODE3
    {
        if (!Mode2Complete)
        {
            #Call MODE2
        }
        if (!Mode2Complete) { Exit }
        DoMode3
    }
}

Please note "MODEx" is just an example. The actual conditions will not be in numerical order like this. They will be different words.

Any ideas how to make this happen?

Appleoddity
  • 647
  • 1
  • 6
  • 21
  • 2
    Looks like you are building a state machine of sorts...don't use `switch`, and try `if` statements, refactored functions, etc. for full flow control. – Kory Gill Oct 13 '17 at 19:28
  • You may want to consider creating a flowchart to determine workflow, and where repetitive loops occur; then design your code based off of that. You can make flowcharts free online at https://www.draw.io/ if you don't have Visio or something. – TheMadTechnician Oct 13 '17 at 19:50

1 Answers1

1

Using GetNewClosure to store state inside scriptblocks. If your code needs external variables inside scriptblocks, consider passing them as arguments to the corresponding scriptblocks.

Example:

# Setup scriptblocks for switch statement and dependencies.
# Use 'GetNewClosure' to capture variables (e.g.: $ModeComplete)

$Alpha = {
    if (!$ModeComplete) {
        'Alpha'
        $ModeComplete = $true
    }
}.GetNewClosure()

$Beta = {
    . $Alpha

    if (!$ModeComplete) {
        'Beta'
        $ModeComplete = $true
    }
}.GetNewClosure()

$Gamma = {
    . $Beta

    if (!$ModeComplete) {
        'Gamma'
        $ModeComplete = $true
    }
}.GetNewClosure()


# Helper scriptblock, will execute scriptblock
# from varible named as current switch condition
$ExecuteCurrentMode = {
    . (Get-Variable -Name $_ -ValueOnly)
}

# Mode
$Mode = 'Gamma'

# Switch
switch ($Mode) {
    'Alpha' {
        . $ExecuteCurrentMode $_
    }

    'Beta' {
        . $ExecuteCurrentMode $_
    }

    'Gamma' {
        . $ExecuteCurrentMode $_
    }
}

Result

Alpha
Beta
Gamma
beatcracker
  • 6,714
  • 1
  • 18
  • 41