2010-05-11 7 views
8

जनरल कोडडिफ़ॉल्ट मूल्य वाले पैरामीटर्स PsBoundParameters में नहीं हैं?

इस कोड पर विचार करें:

PS> function Test { param($p='default value') $PsBoundParameters } 
PS> Test 'some value' 
Key                Value 
---                ----- 
p                 some value 
PS> Test 
# nothing 

मैं उम्मीद करेंगे कि $PsBoundParameters दोनों ही मामलों पर $p चर के लिए रिकॉर्ड होते हैं। क्या यह सही व्यवहार है?

प्रश्न

मैं splatting कि कार्यों का एक बहुत कुछ के लिए इस तरह काम करेगा उपयोग करना चाहते हैं:

function SomeFuncWithManyRequiredParams { 
    param(
    [Parameter(Mandatory=$true)][string]$p1, 
    [Parameter(Mandatory=$true)][string]$p2, 
    [Parameter(Mandatory=$true)][string]$p3, 
    ...other parameters 
) 
    ... 
} 
function SimplifiedFuncWithDefaultValues { 
    param(
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
    ...other parameters 
) 
    SomeFuncWithManyRequiredParams @PsBoundParameters 
} 

मैं सभी पैरामीटर प्रगणित साथ SomeFuncWithManyRequiredParams कॉल करने के लिए नहीं करना चाहते हैं:

SomeFuncWithManyRequiredParams -p1 $p1 -p2 $p2 -p3 $p3 ... 

क्या यह संभव है?

+0

प्रश्न पूछने वाले प्रत्येक पैरामीटर के लिए मुझे यहां दो प्रश्न पूछना होगा: कुछ फनक के पास SimplifiedFunc के समान डिफ़ॉल्ट मान क्यों नहीं है? और, यदि डिफ़ॉल्ट को अलग होने की आवश्यकता है, तो SimplifiedFunc उपयोगकर्ता को डिफ़ॉल्ट को ओवरराइड करने की अनुमति क्यों देता है (क्योंकि, उस स्थिति में, वे केवल कुछफनक को ओवरराइड करने के लिए सीधे कॉल कर सकते हैं)? – jpaugh

उत्तर

5

यह इस बात पर निर्भर करता है कि आप "बाध्य" को कैसे परिभाषित करते हैं, यानी मुझे लगता है कि उपयोगकर्ता द्वारा प्रदत्त मान या फ़ंक्शन द्वारा प्रदान किए गए डिफ़ॉल्ट मान से मूल्य निर्धारित है? ईमानदारी से, यह मुझे आश्चर्य नहीं करता है कि यह इस तरह से व्यवहार करता है क्योंकि मैं उपयोगकर्ता इनपुट से पूर्व-बाध्य होने का मतलब "बाध्य" देखता हूं।

function SimplifiedFuncWithDefaultValues { 
    param( 
    [Parameter(Mandatory=$false)][string]$p1='default for p1', 
    [Parameter(Mandatory=$false)][string]$p2='default for p2', 
    [Parameter(Mandatory=$false)][string]$p3='default for p3', 
    ...other parameters 
) 
    if (!$PSBoundParameters.ContainsKey(p1)) 
    { 
    $PSBoundParameters.p1 = 'default for p1' 
    } 
    # rinse and repeat for other default parameters. 
    SomeFuncWithManyRequiredParams @PSBoundParameters 
} 
+0

ठीक है, मैं सहमत हूं कि '$ PSBoundParameters' में केवल स्पष्ट रूप से आपूर्ति किए गए तर्क हो सकते हैं, परिभाषा पर निर्भर करता है। फिर मेरे पास अपेक्षित सभी पैरामीटर और मान * प्राप्त करने का तरीका होना चाहिए। – stej

+0

आपके द्वारा प्रस्तावित समाधान को ध्यान में रखते हुए: आपका कोड 'SomeFuncWithManyRequiredParams -p1 $ p1 -p2 $ p2 -p3 $ p3' से लंबा है। और यदि 'SimplifiedFuncWithDefaultValues' फ़ंक्शन में सभी पैराम डिफ़ॉल्ट मान हैं तो मुझे कोई फर्क नहीं पड़ता है। – stej

+0

मुझे एक स्वचालित चर के माध्यम से इच्छित जानकारी प्राप्त करने का कोई तरीका नहीं दिख रहा है। शायद आप एक एमएस कनेक्ट सुझाव फाइल करना चाहते हो सकता है। आपके उत्तरों के लिए –

0

आप नीचे दिए गए Add-Variable समारोह के लिए इसी तरह एक सहायक समारोह इस्तेमाल कर सकते हैं: वैसे भी, आप $ PSBoundParameters चर जैसे पैचिंग के द्वारा इस का समाधान कर सकते

function SimplifiedFuncWithDefaultValues { 
    param(
     [Parameter(Mandatory=$false)][string]$p1='default for p1', 
     [Parameter(Mandatory=$false)][string]$p2='default for p2', 
     [Parameter(Mandatory=$false)][string]$p3='default for p3', 
     ...other parameters 
    ) 

    $PSBoundParameters | Add-Variable p1, p2, p3 

    SomeFuncWithManyRequiredParams @PSBoundParameters 
} 

function Add-Variable { 
    param(
     [Parameter(Position = 0)] 
     [AllowEmptyCollection()] 
     [string[]] $Name = @(), 
     [Parameter(Position = 1, ValueFromPipeline, Mandatory)] 
     $InputObject 
    ) 

    $Name | 
    ? {-not $InputObject.ContainsKey($_)} | 
    % {$InputObject.Add($_, (gv $_ -Scope 1 -ValueOnly))} 
} 
5

मैं जानता हूँ कि इस सवाल का बहुत पुराना है, लेकिन मुझे हाल ही में ऐसा कुछ करने की ज़रूरत थी (बहुत सारे डिफ़ॉल्ट पैरामीटर के साथ छेड़छाड़ करना चाहता था)। मैं इस के साथ आया था और यह बहुत अच्छी तरह से काम:

$params = @{} 
foreach($h in $MyInvocation.MyCommand.Parameters.GetEnumerator()) { 
    try { 
     $key = $h.Key 
     $val = Get-Variable -Name $key -ErrorAction Stop | Select-Object -ExpandProperty Value -ErrorAction Stop 
     if (([String]::IsNullOrEmpty($val) -and (!$PSBoundParameters.ContainsKey($key)))) { 
      throw "A blank value that wasn't supplied by the user." 
     } 
     Write-Verbose "$key => '$val'" 
     $params[$key] = $val 
    } catch {} 
} 

बेशर्म आगे प्लग: मैं एक blog post which has more explanation and a sample usage script में इस बारी का फैसला किया।

संबंधित मुद्दे