@@ -427,7 +427,7 @@ function Get-Turtle {
427
427
. EXAMPLE
428
428
# We can draw a 'Sierpinski Snowflake' with multiple Sierpinski Triangles.
429
429
turtle @('rotate', 30, 'SierpinskiTriangle',42,4 * 12)
430
- . EXAMPLE
430
+ . EXAMPLE
431
431
turtle @('rotate', 45, 'SierpinskiTriangle',42,4 * 24)
432
432
#>
433
433
[CmdletBinding (PositionalBinding = $false )]
@@ -456,14 +456,33 @@ function Get-Turtle {
456
456
# If the input object is not a turtle object, it will be ignored and a new turtle object will be created.
457
457
[Parameter (ValueFromPipeline )]
458
458
[PSObject ]
459
- $InputObject
459
+ $InputObject ,
460
+
461
+ [switch ]
462
+ $AsJob
460
463
)
461
464
462
465
begin {
463
466
# Get information about our turtle pseudo-type.
464
- $turtleType = Get-TypeData - TypeName Turtle
467
+ $turtleType = Get-TypeData - TypeName Turtle
468
+ $turtleTypes = @ (
469
+ $turtleType
470
+ # Real types would work to, and we may support them in the future
471
+ # [Math]
472
+ )
473
+
465
474
# any member name is a potential command
466
- $memberNames = $turtleType.Members.Keys
475
+ $memberNames = @ (
476
+ foreach ($typeInfo in $turtleTypes ) {
477
+ if ($typeInfo.Members -is [Collections.IDictionary ]) {
478
+ $typeInfo.Members.Keys
479
+ }
480
+
481
+ <# elseif ($typeInfo -is [Type]) {
482
+ $typeInfo | Get-Member -Static | Select-Object -ExpandProperty Name
483
+ }#>
484
+ }
485
+ )
467
486
468
487
# We want to sort the member names by length, in case we need them in a pattern or want to sort quickly.
469
488
$memberNames = $memberNames | Sort-Object @ {Expression = { $_.Length };Descending = $true }, name
@@ -495,15 +514,42 @@ function Get-Turtle {
495
514
}
496
515
}
497
516
498
- process {
517
+ process {
518
+ # If we were piped in a Turtle,
499
519
if ($PSBoundParameters.InputObject -and
500
520
$PSBoundParameters.InputObject.pstypenames -eq ' Turtle' ) {
521
+ # make it the current turtle
501
522
$currentTurtle = $PSBoundParameters.InputObject
502
523
} elseif ($PSBoundParameters.InputObject ) {
503
524
# If input was passed, and it was not a turtle, pass it through.
504
525
return $PSBoundParameters.InputObject
505
526
}
506
527
528
+ # region -AsJob
529
+ # If we wanted to run a background job
530
+ if ($PSBoundParameters.AsJob ) {
531
+ # remove the -AsJob variable from our parameters
532
+ $null = $PSBoundParameters.Remove (' AsJob' )
533
+
534
+ # and then start a thread job that will import the module and run the command.
535
+ return Start-ThreadJob - ScriptBlock {
536
+ param ([Collections.IDictionary ]$IO )
537
+ Import-Module - Name $io.ModulePath
538
+ $argList = @ ($IO.ArgumentList )
539
+ if ($IO.InputObject ) {
540
+ $io.InputObject | & $io.CommandName @argList
541
+ } else {
542
+ & $io.CommandName @argList
543
+ }
544
+ } - ArgumentList (
545
+ [Ordered ]@ {
546
+ ModulePath = $MyInvocation.MyCommand.ScriptBlock.Module.Path -replace ' \.psm1$' , ' .psd1'
547
+ CommandName = $MyInvocation.MyCommand.Name
548
+ } + $PSBoundParameters
549
+ )
550
+ }
551
+ # endregion -AsJob
552
+
507
553
if (-not $currentTurtle.Invocations ) {
508
554
$currentTurtle | Add-Member NoteProperty Invocations - Force @ (, $invocationInfo )
509
555
} elseif ($currentTurtle.Invocations -is [object []]) {
@@ -531,16 +577,14 @@ function Get-Turtle {
531
577
$arg -split ' \s{1,}'
532
578
} else {
533
579
$arg
534
- }
580
+ }
535
581
} else {
536
582
# otherwise, leave the argument alone.
537
583
$arg
538
584
}
539
585
})
540
586
541
- # If any brackets are used, we want to balance them all now, and error if they appear unbalanced.
542
- $bracketsOnly = $wordsAndArguments -replace ' ^[\[\]]' -join ' '
543
-
587
+ # If any brackets are used, we want to balance them all now, and error if they appear unbalanced.
544
588
# Since we want to know the exact index, we walk thru matches
545
589
$depth = 0
546
590
# and keep track of when it became unbalanced.
600
644
$arg = $wordsAndArguments [$argIndex ]
601
645
# If the argument is not in the member names list, we can complain about it.
602
646
if ($arg -notin $memberNames ) {
603
- if (-not $currentMember -and $arg -is [string ] -and " $arg " .Trim()) {
647
+ if (
648
+ # (we might not want to, if it starts with a bracket)
649
+ -not $currentMember -and $arg -is [string ] -and
650
+ " $arg " .Trim() -and $arg -notmatch ' ^\['
651
+ ) {
604
652
Write-Warning " Unknown command '$arg '."
605
653
}
606
654
continue
611
659
$currentMember = $arg
612
660
$memberInfo = $turtleType.Members [$currentMember ]
613
661
662
+ if (-not $memberInfo ) {
663
+ $memberInfo = foreach ($typeInfo in $turtleTypes ) {
664
+ if ($typeInfo.Members -is [Collections.IDictionary ] -and $typeInfo.Members [$currentMember ]) {
665
+ $typeInfo ; break
666
+ }
667
+ if ($typeInfo ::$currentMember ) {
668
+ $typeInfo ::$currentMember
669
+ break
670
+ }
671
+ }
672
+ }
673
+
614
674
# If it's an alias
615
675
if ($memberInfo.ReferencedMemberName ) {
616
676
# try to resolve it.
684
744
# and call the script, splatting positional parameters
685
745
# (this allows more complex binding, like ValueFromRemainingArguments)
686
746
. $currentTurtle .$currentMember.Script @argList
687
- } else {
688
- # Otherwise, we pass the parameters directly to the method
747
+ }
748
+ elseif ( $currentTurtle . $currentMember .Invoke ) {
689
749
$currentTurtle .$currentMember.Invoke ($argList )
690
- }
691
-
750
+ } elseif ($memberInfo.Invoke ) {
751
+ $memberInfo.Invoke ($argList )
752
+ } elseif ($memberInfo -is [ValueType ]) {
753
+ $memberInfo
754
+ }
692
755
} else {
693
756
# otherwise, just invoke the method with no arguments.
694
757
$currentTurtle .$currentMember.Invoke ()
716
779
}
717
780
} else {
718
781
# otherwise, lets get the property
719
- $currentTurtle .$currentMember
782
+
783
+ if ($null -ne $currentTurtle .$currentMember ) {
784
+ $currentTurtle .$currentMember
785
+ } elseif ($memberInfo -is [ValueType ]) {
786
+ $memberInfo
787
+ }
788
+
720
789
}
721
790
}
722
791
0 commit comments