PowerShell - if statement condition that produces multiple results - powershell

Please consider this silly example:
if (1..3) { "true" }
The above produces the output true.
My question: How does the if statement handle a case like this where multiple values are output by the conditional? Is the "true" output the result of the "3" (the last case)? Or is some other logic at work? Thanks.

The observed behavior is explained (to some extent) in this blog post. Basically, if an expression evaluates to 0 it's interpreted as false, otherwise as true. Examples:
0 => False
1 => True
"0" => True (because it's a string of length 1)
"" => False (because it's a string of length 0)
#() => False
#(0) => False (this one's a little surprising)
#(0,1) => True
#("0") => True

The above produces the output true, as expected.
Why do you expect it to output "true"?
How does the if statement handle a case like this where multiple values are output by the conditional?
The conditional does not "output" any values. It always evaluates to "true" or "false". The question remaining is, why does it evaluate to true (or false).
The code
if (1..3) { "true" }
is equal to
if (#(1,2,3)) { "true" }
is equal to
$array = #(1,2,3)
if ($array) { "true" }
behaves as
if ($array.Length -gt 0) { "true" }
So not individual elements are tested, but rather if the array contains any elements.
For example, the following will not print "true":
if (#()) { "true" }
Update If the array contains only one value, it looks (I coudn't find any normative documentation on that), as if the array is treated as a scalar value using the one element inside.
So
if (#(0))
if (#(0.0))
if (#(1))
if (#(-1))
if (,$null))
if (,"false"))
is treated as
if (0) --> false
if (0.0) --> false
if (1) --> true
if (-1) --> true
if ($null) --> false
if ("false") --> true

1..3 results in an array with 3 items
PS> (1..3).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS> (1..3).Length
3
If there is at least one item in the array the if considers it true
PS> if (#()) { "true" } else { "false" }
false
PS> if (#(1)) { "true" } else { "false" }
true
PS> if (#(1,2)) { "true" } else { "false" }
true

Related

Perl module XML::Compile::WSDL11: Body isn't added to request

I'm trying to build a WSDL client using XML::Compile::WSDL11 and this WSDL. The Operation in question is GetBGList3.
The problem is: The created request doesn't contain the body.
The example code is:
use XML::Compile::SOAP11;
use XML::Compile::WSDL11;
use XML::Compile::Transport::SOAPHTTP;
use Log::Report mode => 'VERBOSE'; # or 'VERBOSE' 'DEBUG'
my $wsdl_file="OpenScape-Voice.wsdl";
my $url="http://127.0.0.1:80/test";
my $ope="GetBGList3";
my $wsdl = XML::Compile::WSDL11->new;
$wsdl->addWSDL($wsdl_file);
$wsdl->compileCall($ope,address => $url);
my $hiqHEADER =
# Describing complex tns:hiqHEADER
# {urn:openscape-voice}hiqHEADER
# xmlns:tns urn:openscape-voice
# is a tns:hiqGLOBALHEADER
{ # sequence of InterfaceWSDL, OperatorId, ClientId
# is a xs:string
# is nillable, hence value or NIL
# is optional
InterfaceWSDL => "NIL",
# is a xs:string
# is nillable, hence value or NIL
# is optional
OperatorId => "myid",
# is a xs:string
# is nillable, hence value or NIL
# is optional
ClientId => "NIL", }
;
# Body part 'Body' is content for element tns:GetBGList3
my $Body =
# Describing complex tns:GetBGList3
# {urn:openscape-voice}GetBGList3
# xmlns:tns urn:openscape-voice
# xmlns:xs http://www.w3.org/2001/XMLSchema
# is an unnamed complex
{ # sequence of GetBGListRequest
# is a tns:GetBGListRequest
GetBGListRequest =>
{ # sequence of OperatorId, NumberPlanName, BGName,
# DNReserveEnabled, Paging, GetBGListDataOptionList,
# GetBGListSortList
# is a xs:string
# is nillable, hence value or NIL
# is optional
OperatorId => "myid",
# is a xs:string
# is nillable, hence value or NIL
# is optional
NumberPlanName => "NIL",
# is a xs:string
# is nillable, hence value or NIL
# is optional
BGName => "NIL",
# is a xs:boolean
# is nillable, hence value or NIL
# is optional
DNReserveEnabled => "true",
# is a tns:Paging
# is nillable, as: Paging => NIL
# is optional
Paging =>
{ # sequence of PageSize, PageNumber
# is a xs:int
PageSize => 42,
# is a xs:int
PageNumber => 42,
},
# is a tns:GetBGListDataOptionList
# is nillable, as: GetBGListDataOptionList => NIL
# is optional
GetBGListDataOptionList =>
{ # sequence of GetBGListDataOptionItem
# is a tns:GetBGListDataOptionItem
# occurs any number of times
GetBGListDataOptionItem =>
[ { # sequence of GetBGListDataOption
# is a xs:string
# is nillable, hence value or NIL
# is optional
# Enum: BgListDataInclBGDisplayNum
GetBGListDataOption => "BgListDataInclBGDisplayNum",
},
],
},
# is a tns:GetBGListSortList
# is nillable, as: GetBGListSortList => NIL
# is optional
GetBGListSortList =>
{ # sequence of GetBGListSortElement
# is a tns:GetBGListSortElement
# occurs any number of times
GetBGListSortElement =>
[ { # sequence of GetBGListSortType, SortOrder
# is a xs:string
# is nillable, hence value or NIL
# is optional
# Enum: BGListSortBGName
GetBGListSortType => "BGListSortBGName",
# is a xs:string
# is nillable, hence value or NIL
# is optional
# Enum: SortOrderAscending SortOrderDescending
SortOrder => "SortOrderAscending",
},
],
},
},
}
;
# Call with the combination of parts.
my #params = (
hiqHEADER => $hiqHEADER,
Body => $Body,
);
my ($answer, $trace) = $wsdl->call($ope,#params);
Running the script creates the warning
warning: unused values GetBGListRequest
Not providing the $Body creates this error:
error: required value for element `GetBGListRequest' missing at tns:GetBGList3
This means: the Body seems to be requested / needed to build the request - but finally it isn't added to the request.
The question now is: How can I achieve it to get the body added to the request, too?

Is it possible to create specific constant elements of a PowerShell array?

Let's say I have array Grid that was initialized with
$Grid = #(#(1..3), #(4..6), #(7..9))
and I want to change Grid[0][0] to value "Test" but I want to make it unchangeable, is there a way I could to that?
So far I've tried playing around with classes that allow read-only or constant declarations through the class as opposed to using New-Variable/Set-Variable but it doesn't affect the index itself but the individual element as in
$Grid[0][0] = [Array]::AsReadOnly(#(1,2,3))
$Grid[0][0] # 1 \n 2 \n 3
$Grid[0][0].IsReadOnly # True
$Grid[0][0] = "test"
$Grid[0][0] # test
I assume this is due to $Grid[0][0] being read-only as opposed to constant and the behaviour I experienced supported that:
$test = [Array]::AsReadOnly(#(1,2,3,4))
$test[0]=1 # Errors
$test = "test"
$test # test
$Grid = #(#(1..3), #(4..6), #(7..9))
$Grid[0][0] = [Array]::AsReadOnly(#(1,2,3))
$Grid[0][0][0] = 1 # Errors
$Grid[0][0] = "test"
$Grid[0][0] # test
I'm not sure what to try next and I know that this is very simple with classes but I am not looking for that as a solution.
You'll have to make both dimensions of your nested array read-only to prevent anyone from overwriting $grid[0]:
$grid =
[array]::AsReadOnly(#(
,[array]::AsReadOnly(#(1,2,3))
,[array]::AsReadOnly(#(3,2,1))
))
(the unary , is not a typo, it prevents PowerShell from "flattening" the resulting read-only collection)
Now $grid should behave as you expect:
$grid[0] # 1,2,3
$grid[0][0] # 1
$grid[0][0] = 4 # error
$grid[0] = 4 # error
If you want to be able to prevent writing to individual "cells", you'll have to define a custom type:
using namespace System.Collections
class Grid {
hidden [int[,]] $data
hidden [bool[,]] $mask
Grid([int]$width,[int]$height){
$this.mask = [bool[,]]::new($width, $height)
$this.data = [int[,]]::new($width, $height)
}
[int]
Get([int]$x,[int]$y)
{
if(-not $this.CheckBounds($x,$y)){
throw [System.ArgumentOutOfRangeException]::new()
}
return $this.data[$x,$y]
}
Set([int]$x,[int]$y,[int]$value)
{
if(-not $this.CheckBounds($x,$y)){
throw [System.ArgumentOutOfRangeException]::new()
}
if(-not $this.mask[$x,$y])
{
$this.data[$x,$y] = $value
}
else
{
throw [System.InvalidOperationException]::new("Cell [$x,$y] is currently frozen")
}
}
Freeze([int]$x,[int]$y)
{
if(-not $this.CheckBounds($x,$y)){
throw [System.ArgumentOutOfRangeException]::new()
}
$this.mask[$x,$y] = $true
}
Unfreeze([int]$x,$y)
{
if(-not $this.CheckBounds($x,$y)){
throw [System.ArgumentOutOfRangeException]::new()
}
$this.mask[$x,$y] = $false
}
hidden [bool]
CheckBounds([int]$x,[int]$y)
{
return (
$x -ge $this.data.GetLowerBound(0) -and
$x -le $this.data.GetUpperBound(0) -and
$y -ge $this.data.GetLowerBound(1) -and
$y -le $this.data.GetUpperBound(1)
)
}
}
Now you can do:
$grid = [Grid]::new(5,5)
$grid.Set(0, 0, 1) # Set cell value
$grid.Get(0, 0) # Get cell value
$grid.Freeze(0, 0) # Now freeze cell 0,0
$grid.Set(0, 0, 2) # ... and this will now throw an exception
$grid.Set(0, 1, 1) # Setting any other cell still works
If you want native support for index expressions (ie. $grid[0,0]), the Grid class will need to implement System.Collections.IList

How to convert a string value to a dynamic data type in PowerShell?

Is it possible to assign a string value to a variable of a different type given that the data type is not known in advance? For example, in the sample below, how do I update the values of the $values hash without changing their data types:
$values = #{
"Boolean" = $true
"Int" = 5
"DateTime"= (Get-Date)
"Array" = #("A", "B", "C")
}
$stringValues = #{
"Boolean" = 'false'
"Int" = '10'
"DateTime"= '2019-01-02 14:45:59.146'
"Array" = '#("X", "Y", "Z")'
}
"INITIAL VALUES:"
foreach ($key in $values.Keys) {
($key + " = " + $values[$key] + " (" + $values[$key].GetType().FullName + ")")
}
"`nUPDATING..."
foreach ($key in $stringValues.Keys) {
$values[$key] = $stringValues[$key]
}
"`nUPDATED VALUES:"
foreach ($key in $values.Keys) {
($key + " = " + $values[$key] + " (" + $values[$key].GetType().FullName + ")")
}
OUTPUT:
INITIAL VALUES:
DateTime = 04/23/2019 16:54:13 (System.DateTime)
Array = A B C (System.Object[])
Boolean = True (System.Boolean)
Int = 5 (System.Int32)
UPDATING...
UPDATED VALUES:
DateTime = 2019-01-02 14:45:59.146 (System.String)
Array = #("X", "Y", "Z") (System.String)
Boolean = false (System.String)
Int = 10 (System.String)
I need the updated values to match the original data types and not just get converted to System.String.
I am flexible on the contents of the strings. E.g. a string holding a boolean false value may be $false/false/[boolean]false/[boolean]$false/etc or a string holding an array may use a different formatting (basically, whatever is easier to convert the string to a proper data type).
In essence, I want to simulate whatever the ConvertFrom-Json cmdlet does when it sets the object property from a JSON string, only in my case, I do not have a JSON structure.
(In case someone wonders what I'm trying to do: I am trying to add an INI file parser to my ConfigFile module, and no, I cannot just use a hash to return the INI settings; I need to load the values into the corresponding PSVariables and for this to work, I need to convert strings to proper data types.)
So you want to cast/convert the new value to the type of the old value.
The idea needs to cast from a variable,
here is a related question powershell-type-cast-using-type-stored-in-variable
The answer suggest:
You can roughly emulate a cast using the following method:
[System.Management.Automation.LanguagePrimitives]::ConvertTo($Value, $TargetType)
The following changed routine shows: it isn't that simple, especially when the new data needs overloads/other parameters in the conversion.
"UPDATING..."
foreach ($key in $stringValues.Keys) {
$values[$key] = [System.Management.Automation.LanguagePrimitives]::ConvertTo(
$stringValues[$key], $values[$key].gettype())
}
My German locale error message:
Ausnahme beim Aufrufen von "ConvertTo" mit 2 Argument(en): "Der Wert "2019-01-02 14:45.59.146" kann nicht in den Typ
"System.DateTime" konvertiert werden. Fehler: "Die Zeichenfolge wurde nicht als gültiges DateTime erkannt.""
In Zeile:2 Zeichen:5
+ $values[$key] = [System.Management.Automation.LanguagePrimitives] ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : PSInvalidCastException
And the unsufficient result:
DateTime = 04/24/2019 09:49:19 (System.DateTime)
Array = #("X", "Y", "Z") (System.Object[])
Boolean = True (System.Boolean)
Int = 10 (System.Int32)
You may elaborate yourself on this idea, handling old types/new data more individually.
You can use a custom class in lieu of a hashtable; unlike hashtable keys, the properties of custom classes can be specifically typed.
With scalar values, you can then simply let PowerShell perform the from-string conversion for you - except that Boolean strings need special treatment (see comments in source code below).
With arrays, things are trickier. The solution below uses [System.Management.Automation.PSParser]::Tokenize() to parse the string, but is currently limited to recognizing string and number literals.
Note: It is tempting to use Invoke-Expression on the entire array, but that would be a security risk, because it opens to the door to arbitrary code execution. While there are legitimate uses - such as on a string known to represent a number below - Invoke-Expression should generally be avoided.
(If you don't want to define classes, you can derive the types from the values of hashtable $values and use [System.Management.Automation.LanguagePrimitives]::ConvertTo() to convert the strings to those types, as shown in LotPings' answer, though note that arrays and Booleans still need special treatment as shown below.)
# Define a custom [Values] class
# with specifically typed properties.
class Values {
[bool] $Boolean
[int] $Int
[datetime] $DateTime
[Array] $Array
}
# Instantiate a [Values] instance
$values = [Values] #{
Boolean = $true
Int = 5
DateTime= (Get-Date)
Array = #("A", "B", "C")
}
$stringValues = #{
Boolean = 'false'
Int = '10'
DateTime = '2019-01-02 14:45:59.146'
Array = '#("X", "Y", "Z")'
}
"INITIAL VALUES:"
foreach ($key in $values.psobject.properties.Name) {
($key + " = " + $values.$key + " (" + $values.$key.GetType().FullName + ")")
}
""
"UPDATING..."
foreach ($key in $stringValues.Keys) {
switch ($key) {
'Array' {
# Parse the string representation.
# Assumptions and limitations:
# The array is flat.
# It is sufficient to only support string and numeric constants.
# No true syntax validation is needed.
$values.$key = switch ([System.Management.Automation.PSParser]::Tokenize($stringValues[$key], [ref] $null).Where( { $_.Type -in 'String', 'Number' })) {
{ $_.Type -eq 'String' } { $_.Content; continue }
{ $_.Type -eq 'Number' } { Invoke-Expression $_Content; continue }
}
continue
}
'Boolean' { # Boolean scalar
# Boolean strings need special treatment, because PowerShell considers
# any nonempty string $true
$values.$key = $stringValues[$key] -notin 'false', '$false'
continue
}
default { # Non-Boolean scalar
# Let PowerShell perform automatic from-string conversion
# based on the type of the [Values] class' target property.
$values.$key = $stringValues[$key]
}
}
}
""
"UPDATED VALUES:"
foreach ($key in $values.psobject.properties.Name) {
($key + " = " + $values.$key + " (" + $values.$key.GetType().FullName + ")")
}
This yields:
INITIAL VALUES:
Boolean = True (System.Boolean)
Int = 5 (System.Int32)
DateTime = 04/24/2019 14:45:29 (System.DateTime)
Array = A B C (System.Object[])
UPDATING...
UPDATED VALUES:
Boolean = True (System.Boolean)
Int = 10 (System.Int32)
DateTime = 01/02/2019 14:45:59 (System.DateTime)
Array = X Y Z (System.Object[])
Agreed on the Write-Host thing. It should really only be used to leverage color output and some specific format cases. Output to the screen is the default as you'll see in my response.
You could do the below, but that date string is a bit odd, well, for me, well, I've not seen anyone use that format. So, I modified it for US style, but change as needed for your language.
$values = #{
'Boolean' = $true
'Int' = 5
'DateTime'= (Get-Date)
'Array' = #('A', 'B', 'C')
}
$stringValues = #{
'Boolean' = 'false'
'Int' = '10'
'DateTime'= '2019-01-02 14:45:59'
'Array' = "#('X', 'Y', 'Z')"
}
'INITIAL VALUES:'
foreach ($key in $values.Keys)
{
"$key = $($values[$key]) $($values[$key].GetType())"
}
"`nUPDATING..."
foreach ($key in $stringValues.Keys)
{
switch ($key)
{
Boolean {[Boolean]$values[$key] = $stringValues['$'+$key]}
Int {[Int]$values[$key] = $stringValues[$key]}
DateTime {[DateTime]$values[$key] = $stringValues[$key]}
Array {[Array]$values[$key] = $stringValues[$key]}
default {'The value could not be determined.'}
}
}
"`nUPDATED VALUES:"
foreach ($key in $values.Keys)
{
"$key = $($values[$key]) $($values[$key].GetType())"
}
# Results
INITIAL VALUES:
DateTime = 04/24/2019 01:44:17 datetime
Array = A B C System.Object[]
Boolean = True bool
Int = 5 int
UPDATING...
UPDATED VALUES:
DateTime = 01/02/2019 14:45:59 datetime
Array = #("X", "Y", "Z") System.Object[]
Boolean = False bool
Int = 10 int
Thanks to #LotPings, #mklement0, and #postanote for giving me a few ideas, so here is the solution I will go with:
$values = #{
"Boolean" = $true
"Int" = 5
"DateTime"= (Get-Date)
"Array" = #("A", "B", "C")
}
$stringValues = #{
"Boolean" = 'false'
"Int" = '10'
"DateTime"= '2019-01-31 14:45:59.005'
"Array" = 'X,Y,Z'
}
"INITIAL VALUES:"
foreach ($key in $values.Keys) {
($key + " = " + $values[$key] + " (" + $values[$key].GetType().FullName + ")")
}
"`nUPDATING..."
foreach ($key in $stringValues.Keys) {
$value = $stringValues[$key]
if ($values[$key] -is [Array]) {
$values[$key] = $value -split ','
}
elseif (($values[$key] -is [Boolean]) -or ($values[$key] -is [Switch])) {
$values[$key] = $value -notin 'false', '$false', '0', ''
}
else {
$values[$key] = [System.Management.Automation.LanguagePrimitives]::ConvertTo($value, $values[$key].GetType())
}
}
"`nUPDATED VALUES:"
foreach ($key in $values.Keys) {
($key + " = " + $values[$key] + " (" + $values[$key].GetType().FullName + ")")
}
OUTPUT:
INITIAL VALUES:
DateTime = 04/25/2019 09:32:31 (System.DateTime)
Array = A B C (System.Object[])
Boolean = True (System.Boolean)
Int = 5 (System.Int32)
UPDATING...
UPDATED VALUES:
DateTime = 01/31/2019 14:45:59 (System.DateTime)
Array = X Y Z (System.String[])
Boolean = False (System.Boolean)
Int = 10 (System.Int32)
I adjusted the format of the array in the string value (which, as I mentioned in the question, was an option). The actual code that will use this will be a bit different, but the basic idea is here. The only caveat that I noticed is that the array data type gets changed from object[] to string[]. Ideally, I'd like to keep it as-is, but it would not change the functionality of the code, so it is fine. Thanks again to all for the ideas and corrections, and if you come up with better alternatives, feel free to post.

Test Connection and loop if true or false (change colors...) [duplicate]

Something is really weird with this language. I'm trying to execute a function and use its result value as condition. This is my code:
function Get-Platform()
{
# Determine current Windows architecture (32/64 bit)
if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null)
{
echo "x64"
return "x64"
}
else
{
echo "x86"
return "x86"
}
}
if (Get-Platform -eq "x64")
{
echo "64 bit platform"
}
if (Get-Platform -eq "x86")
{
echo "32 bit platform"
}
The expected output is this:
x64
64 bit platform
But the actual output is this:
64 bit platform
32 bit platform
What's going on here? How can this be fixed? I couldn't find any examples on the web that use functions inside an ifcondition. Is that possible at all in Powershell? I'm on Windows 7 with no special setup, so I have whatever PS version comes with it.
If you want to compare the return value of a function in a conditional, you must group the function call (i.e. put it in parentheses) or (as #FlorianGerhardt suggested) assign the return value of the function to a variable and use that variable in the conditional. Otherwise the comparison operator and the other operand would be passed as arguments to the function (where in your case they're silently discarded). Your function then returns a result that is neither "" nor 0 nor $null, so it evaluates to $true, causing both messages to be displayed.
This should do what you want:
...
if ( (Get-Platform) -eq 'x64' ) {
echo "64 bit platform"
}
...
BTW, you should avoid using separate if statements for conditions that are mutually exclusive. For a platform check an if..then..elseif
$platform = Get-Platform
if ($platform -eq "x64") {
...
} elseif ($platform -eq "x86") {
...
}
or a switch statement
Switch (Get-Platform) {
"x86" { ... }
"x64" { ... }
}
would be more appropriate.
I'd also avoid echoing inside the function. Just return the value and do any echoing that might be required in with the returned value. Anything echoed inside the function will also be returned to the caller.
One last note: personally I'd rather not rely on the existence of a particular folder or environment variable for determining the operating system architecture. Using WMI for this task deems me a lot more reliable:
function Get-Platform {
return (gwmi Win32_OperatingSystem).OSArchitecture
}
This function will return a string "32-Bit" or "64-Bit", depending on the operating system architecture.
I think you are comparing a function and not the function result. Also somehow the echo does not work as expected in a function. I usually use Write-Host.
Here is my solution to your problem:
function Get-Platform()
{
# Determine current Windows architecture (32/64 bit)
if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null)
{
Write-Host("x64")
return "x64"
}
else
{
Write-Host("x86")
return "x86"
}
}
$platform = Get-Platform
if ($platform -eq 'x64')
{
echo "64 bit platform"
}
if ($platform -eq 'x86')
{
echo "32 bit platform"
}

check field formmail

i am trying to change this:
foreach $require (#Required) {
# If the required field is the email field, the syntax of the email #
# address if checked to make sure it passes a valid syntax. #
if ($require eq 'email' && !&check_email($Config{$require})) {
push(#error,$require);
}
//////////////////////////////////////////////////////////////////////////////////
sub check_email {
# Initialize local email variable with input to subroutine. #
$email = $_[0];
# If the e-mail address contains: #
if ($email =~ /(#.*#)|(\.\.)|(#\.)|(\.#)|(^\.)/ ||
# the e-mail address contains an invalid syntax. Or, if the #
# syntax does not match the following regular expression pattern #
# it fails basic syntax verification. #
$email !~ /^.+\#(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z0-9]+)(\]?)$/) {
# Basic syntax requires: one or more characters before the # sign, #
# followed by an optional '[', then any number of letters, numbers, #
# dashes or periods (valid domain/IP characters) ending in a period #
# and then 2 or 3 letters (for domain suffixes) or 1 to 3 numbers #
# (for IP addresses). An ending bracket is also allowed as it is #
# valid syntax to have an email address like: user#[255.255.255.0] #
# Return a false value, since the e-mail address did not pass valid #
# syntax. #
return 0;
}
else {
# Return a true value, e-mail verification passed. #
return 1;
}
}
into this:
foreach $require (#Required) {
if ($require eq 'fieldb' && !&check_fieldb($Config{$require})) {
push(#error,$require);
}
///////////////////////////////////////////////////////////////////////////////
sub check_fieldb {
# If field b is under 20% of field a: #
if ($fieldb <=($fielda/100)*20 ) {
# Return a false value, since field b is less than 20% of field a
return 0;
}
else {
# Return a true value, fieldb verification passed. #
return 1;
}
}
but it does not work, always returns as 0.
how would i fix this?
It's impossible to be sure what's wrong without knowing the values of $fielda and $fieldb. My diagnosis is that $fieldb is less than or equal to ($fielda/100)*20
You pass a value to check_fieldb, but you never use it. Why do you pass it? As a commenter noted you should be passing to the function the values you want to check. Are $fielda and $fieldb guaranteed to be correctly initialized before check_fieldb is called?
Do you meant to be saying
foreach my $require (#Required){
if($require eq 'fieldb' && !check_fieldb($value_of_fielda, $value_of_fieldb)){
push(#error, $require);
}
}
# ... later ...
sub check_fieldb($$){
my $fielda = shift;
my $fieldb = shift;
return !($fieldb <=($fielda/100)*20);
}
perhaps?