This is my code :
Function CleanUpOracle
{
if ($Requete)
{
$Requete.Dispose()
}
if ($ExecuteRequete)
{
$ExecuteRequete.Dispose()
}
if ($Transaction)
{
$Transaction.Dispose()
}
if ($OracleConnexion)
{
$OracleConnexion.close()
$OracleConnexion.Dispose()
}
if ($Log.id)
{
$Log.PSObject.Properties.Remove('id')
}
}
I'm testing if a variable exist then {do something}
But in the future I'll many variable to test, I don't want to have hundred lines with that.
How can I optimize this? Maybe with a switch but how?
Thanks !
If you want to conditionally call Dispose against multiple items you can stream them from a list into the ForEach-Object (whose alias is %):
#($Requete, $ExecuteRequete, $Transaction, $OracleConnexion) |
% {if($_) {$_.Dispose()} }
NOTE: I've split this onto multiple lines for readability.
Related
Instead of piping over collections, it's sometimes more convenient to procedurally loop through them. And to avoid differentiating between $_ and $_.Key/$_.Value depending on input, a more consistent key/value handling would be nice:
ForEach-KV $object { Param($k, $v); do-stuff }
However a common type probing has its drawbacks:
#-- iterate over dicts/objects/arrays using scriptblock with Param($k,$v)
function ForEach-KV {
Param($var, $cb, $i=0)
switch ($var.GetType().Name) {
Array { $var | % { $cb.Invoke($i++, $_) } }
HashTable { $var.Keys | % { $cb.Invoke($_, $var[$_]) } }
"Dictionary``2" { $var.Keys | % { $cb.Invoke($_, $var.Item($_)) } }
PSobject { $var.GetIterator() | % { $cb.Invoke($_.Key, $_.Value) } }
PSCustomObject { $var.GetIterator() | % { $cb.Invoke($_.Key, $_.Value) } }
default { $cb.Invoke($i++, $_) }
}
}
Apart from that one irritating type name, there's a bit much duplication here. Which is why I was looking around for duck typing in Powershell.
For hashes and objects, it's easiest/obvious to probe for .getIterator or .getEnumerator (never couldn't quite remember which belongs to which anyway):
switch ($_) {
{ $_.GetEnumerator } { do-loopy }
{ $_.GetIterator } { do-otherloopy }
But now I'm not quite sure what to do about arrays here. There's not that one behaviour indicator in [array]s methods that really sticks out.
.Get() does seem unique (at least not a method in HashTables or PSObjects), but sounds a bit too generic even for type guessing
.Add() might as well be an integer method(?)
.GetUpperBound() etc. come off as a bit too specific already.
So, is there a standard method that says "arrayish", preferrably something that's shared among other numerically-indexed value collections?
If you want to match only arrays:
PS> $x = 1..10
PS> $x.GetType().IsArray
True
or you can check there is integer indexer:
(Get-Member -InputObject $x -Name 'Item' -MemberType 'ParameterizedProperty').Definition -match '\(int index\)'
I have two pieces v-piece and i-piece which are joined together with join_pieces().
Afterwards, the combination of those two pieces are meant to be differenced as a whole by two cubes in the piece() function.
The problem is the only piece showing a difference is the i_piece and not the v_piece which even though it is connected, it is left whole with no subtraction. I have removed the difference() line and checked to make sure the cubes are intersecting both pieces and they are. I have tried a union in case the difference was only accepting one object but it appears to not have changed anything.
Any suggestions, or answers to try? Thanks.
module join_pieces() {
union() {
v_piece();
translate([0,0,-1*stem_height+INSERT]) {
i_piece();
}
}
}
module piece() {
difference() {
join_pieces();
rotate([0,0,45]) {
cube([AIR,V_PIECE_WIDTH*4, RADIUS], center=true);
}
rotate([0,0,135]) {
cube([AIR,V_PIECE_WIDTH*4, RADIUS], center=true);
}
}
}
piece();
Could you show the variable definitions and the other functions used by these modules? I tried running your code with cubes replacing v_piece and i_piece and putting random numbers as the variables. It seems like your code is correct for what you want to do, running the modified version:
module join_pieces() {
union() {
translate([-2, 0, 0]){
#cube([5, 2, 2]);
}
translate([0,-2,-1*3+2]) {
cube([3, 5, 3]);
}
}
}
module piece() {
difference() {
join_pieces();
rotate([0,0,45]) {
cube([1,3*4, 4], center=true);
}
rotate([0,0,135]) {
cube([1,3*4, 4], center=true);
}
}
}
piece();
You can see that what you have here is fine.
Have you made sure none of your other functions are missing a semi-colon and used the # to display your difference pieces?
I have a script that takes about 15 minutes to run, checking various aspects of ~700 VMs. This isn't a problem, but I now want to find devices that have serial ports attached. This is a function I added to check for this:
Function UsbSerialCheck ($vm)
{
$ProbDevices = #()
$devices = $vm.ExtensionData.Config.Hardware.Device
foreach($device in $devices)
{
$devType = $device.GetType().Name
if($devType -eq "VirtualSerialPort")
{
$ProbDevices += $device.DeviceInfo.Label
}
}
$global:USBSerialLookup = [string]::join("/",$ProbDevices)
}
Adding this function adds an hour to the length of time the script runs, which is not acceptable. Is it possible to do this in a more efficient way? All ways I've discovered are variants of this.
Also, I am aware that using global variables in the way shown above is not ideal. I would prefer not to do this; however, I am adding onto an existing script, and using their style/formatting.
Appending to arrays ($arr += $newItem) in a loop doesn't perform well, because it copies all existing elements to a new array. This should provide better performance:
$ProbDevices = $vm.ExtensionData.Config.Hardware.Device `
| ? { $_.GetType().Name -eq 'VirtualSerialPort' } `
| % { $_.DeviceInfo.Label }
I am trying to implement RSpec/Jasmine like BDD framework in Powershell (or at least research the potential problems with making one).
Currently I am having problems with implementing simple before/after functionality. Given
$ErrorActionPreference = "Stop"
function describe()
{
$aaaa = 0;
before { $aaaa = 2; };
after { $aaaa; }
}
function before( [scriptblock]$sb )
{
& $sb
}
function after( $sb )
{
& $sb
}
describe
the output is 0, but I would like it to be 2. Is there any way to achieve it in Powershell (short of making $aaaa global, traversing parent scopes in script blocks till $aaaa is found, making $aaaa an "object" and other dirty hacks:) )
What I would ideally like is a way to invoke a script block in some other scope but I don't have a clue whether it is possible at all. I found an interesting example at https://connect.microsoft.com/PowerShell/feedback/details/560504/scriptblock-gets-incorrect-parent-scope-in-module (see workaround), but am not sure how it works and if it helps me in any way.
TIA
The call operator (&) always uses a new scope. Instead, use the dot source (.) operator:
$ErrorActionPreference = "Stop"
function describe()
{
$aaaa = 0;
. before { $aaaa = 2; };
. after { $aaaa; }
}
function before( [scriptblock]$sb )
{
. $sb
}
function after( $sb )
{
. $sb
}
describe
Note the use of . function to invoke the function in same scope as where `$aaaa is defined.
All, can I run more than one defaction in the body of the rule? or can I only run one?
You can define as many actions in the pre block of a rule as you want. You can have as many actions in the action block of a rule as you want (just enclose the action block in curly braces). For example,
rule first_rule {
select when pageview ".*" setting ()
pre {
notify_one = defaction() { notify("notify_one", "First defaction"); };
notify_two = defaction() { notify("notify_two", "Second defaction"); };
}
{
notify_one();
notify_two();
}
}
So I think the answer to your question is yes.
Your question is a little confusing, but I'll give it a run.
Running actions defined with defaction is just like running system defined actions.
If you want to run more then one action in a rule, you need to wrap them in {} like so:
rule foo {
select when pageview ".*"
{
notify("cheese", "brie");
notify("apple", "golden delicious");
}
}
I seem to recall that a defaction has an implicit, optional 'pre' section, followed by the action(s). To include multiple actions you do need {} as Sam says.
act1 = defaction() {
{
notify("Defaction Demo", "<ul id='demo_id'></ul>");
append("#demo-id", "<li>cheese: brie</li>");
append("#demo-id", "<li>apple: golden delicious</li>");
}
};
That works out to defaction() { { ... } }; but the extra curly braces are required if you want more than one action in a defaction.
See also http://docs.kynetx.com/docs/Defaction