Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's Blog

:

Engineering and troubleshooting by Directory Master!
Ondrej Sevecek's Blog > Posts > Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů
srpen 20
Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

Zkurvená pseudosyntaxe. Příklad, který mě nasral na maximum. Jak známo, když se vrací z funkce pole, tak miláček PowerShell dělá automaticky jednu podělanou konverzi. Když vracíte pole s jedním prvkem, tak on to zkonvertuje jen na ten jeden prvek. Když vracíte víceprvkové pole, tak to v klidu vrátí celé pole. Můžete si to vyzkoušet jednoduše, například s get-process. Stačí, když si pustíte nejprve 1 notepad a zkusíte následující skript. Když to potom zkusíte s více notepady, tak dostanete jiný výsledek get-member:

$poleNeboJeden = get-process notepad
gm -i $poleNeboJeden

To už samo o sobě je na posrání. Protože obvykle nevíte dopředu, jestli vypadne jeden, nebo více. Nemůžete se tedy vždycky odkazovat na člena Count, protože ten u jednotlivých objektů není. Nebo když je, tak má úplně jiný význam, což se samozřejmě projeví až v produkci, ideálně smazáním půlky adčka. No prostě už samo o sobě kokotina.

Dobře. Ale to se dá vyřešit jednoduše. Musíte pro return z funkce použít speciální čárkový operátor, který takto funguje jenom u return: (kdybyste to použili na pole jinde než v return, tak se to pole zapolí do vnitřního pole):

function Get-ArrayAlwaysEvenIfSingleObject ([int] $shitCount)
# Normally, function return values are converted from single 
# member arrays to the single object while more-member arrays remain as arrays
# Example would be with "get-process notepad", which returns either a single object
# or an array of the processes if more then a single notepad is running
# My function, on the other side, returns an array always
# regardles it has no/one/more members. To achieve this functionality
# PowerShell has the special (,) construct
# This function returns array with either 0 or more numbers according to
# the number specified in its input parameter $numberCount
{
  [string[]] $fcResult = @()

  if ($shitCount -gt 0) {

    $fcResult = (1..$shitCount) | % { "shit $_" }
  }

  return (, $fcResult)  # this is always an array
}

Get-ArrayAlwaysEvenIfSingleObject 7

Kůl. Takže výsledek tohoto je vždycky pole, bez ohledu na to, kolik hoven chcete. Funkce je nesmyslná, ale na ukázku to snad stačí. Takže jednu sračku jsme vyřešili, sice člověk zvyklý na jednoduchou a smysluplnou syntaxi by se z toho poblil, ale dobrá.

Horší je, že i nadále nepřestávají padat sračky. Následující dva zápisy se liší jenom v tom, že jsem to ozávorkoval. V prvním případě to nefunguje. Ve druhém už jo, ale obalovat všechno do závorek, to může napadnout jenom nějakýho mentálně stiženýho a případně i zhulenýho inda:

# The expected behavior would be to see just 5,6,7 numbers returned
# but it actually displays all the numbers instead. The reason is
# that it pipes the array as the only object through to the where-object (?)
# instead of piping individual members.
Get-ArrayAlwaysEvenIfSingleObject 7 | select -last 3


# To repair the behavior and get expected results
# you must enclose the function into brackets
(Get-ArrayAlwaysEvenIfSingleObject 7) | select -last 3

Důvodem je zřejmě to, že v prvním případě se pajpuje jenom ten jeden polní objekt, zatímco v druhém to korektně přepajpuje všechny členy pole po jednom.

 

Comments

Re: Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

Co takhle tu proměnou přiřadit do pole rovnou ?
[array]$poleNeboJeden = get-process notepad
gm -i $poleNeboJeden

teď se to chová stejně v 1 i s více notepady
tom on 20.8.2013 14:36

Re: Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

jasně, to ale není ten problém. to se vždycky dá vyřešit. problém je, že PowerShell tu konverzi dělá automaticky a tudíž to člověk musí mít na paměti, že z funkcí poleze buď pole, nebo jeden objekt a musí to vcelku zbytečně přetypovávat.

ale o tomhle ten článek ani není. sice jsem se na tom taky pěkně dlouho nadřel, než jsem objevil ten čárkový operátor pro return, ale opět to nebylo nic podstatného.

ten čárkový operator jsem už používal spokojeně dlouho a v pohodě.

jenomže to jsem nepotřeboval výsledek pajpovat, zatím.

až teď jsem ve svém projektu s 12 500 řádky upravil jednu maličkou, ale hojně používanou funkci, aby taky vracela takto pole, protože musí vracet pole nově, a musel jsem poladit, proč to má najednou 600 errorů.

bože. takový nesyntaktický hnus!
ondass on 20.8.2013 14:52

Re: Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

to co je skutečná sračka je to závorkování před pajpou.
ondass on 20.8.2013 14:53

:D

Som sa dobre pobavil :D
Ondrej Zilinec on 20.8.2013 14:57

Re: Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

Jo, souhlas, je to vopruz. Proto se doporucuje vysledek (kde pocet hodnot neni jasny) dat do @(). Posledni radku funkce

return (, $fcResult)

bych napsal jako return @($fcResult)
a pak uz to funguje pro oba uvedene priklady stejne.
Ale jo, souhlas - je to hnus :)

D.
David on 3.9.2013 8:59

Ina alternativa

Takato alternativa funguje korektne, rozdiel je v tom ze vrati pole objektov (povodna pole stringov):

Function Get-AA ([int] $shitCount)

  $fcResult = @()
  1..$shitcount | % { $fcResult += "shit $_" }
  return $fcResult
}
Rastislav Harcarufka on 11.12.2013 13:28

Re: Zabijůůůů ten PowerShell, zabijůůů, já se na to můžu vysrááát. Nebudu to dělat, nebudůůůů

teď přesně nerozumím jak to myslíte. pokud ale $shitCount bude =1, tak to stejně vrátí jenom jeden objekt a ne pole. Bacha na to.
ondass on 14.12.2013 10:52

Add Comment

Title


Pole Title nemusíte vyplňovat, doplní se to samo na stejnou hodnotu jako je nadpis článku.

Author *


Pole Author nesmí být stejné jako pole Title! Mám to tu jako ochranu proti spamu. Roboti to nevyplní dobře :-)

Body *


Type number two as digit *


Semhle vyplňte číslici dvě. Předchozí antispemové pole nefunguje úplně dokonale, zdá se, že jsou i spamery, které pochopily, že je občas potřeba vyplnit autora :-)

Email


Emailová adresa, pokud na ni chcete ode mě dostat odpověď. Nikdo jiný než já vaši emailovou adresu neuvidí.

Attachments