CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
change string to boolean conversion

 



gef
New User

Jan 4, 2018, 2:33 AM

Post #1 of 6 (707 views)
change string to boolean conversion Can't Post

is there any way to change the internal string to boolean conversion, such that:
* undef, "" => converted to false
* all other strings, including "0" => converted to true

the built-in conversion of "0" to false is terrible for most of my use cases. in particular i prefer to use the boolean operators on strings as follows:

* my $string_var = $string_value || "default value";
(set $string_var to $string_value if this is non-empty, even if it is "0")

* do_something( $string_var ) if $string_var;
(do_something if $string_var is non-empty, also if it is "0")

* if( $string_var && f($string_var) ) { do_something; }
(evaluate f() if $string_var is non-empty, also if it is "0")

i now have to write slightly more complex expressions, using e.g., ($string ne ""). the built-in conversion is useful only in a very few cases. i would happily write more complex equivalent expressions in these very few cases, in order to simplify code for most of the cases.

thanks


BillKSmith
Veteran

Jan 4, 2018, 6:17 AM

Post #2 of 6 (702 views)
Re: [gef] change string to boolean conversion [In reply to] Can't Post

It probably is not possible to do what you ask. However, Perl provides a function (defined) which returns true or false exactly the way you specify. Your three examples can be written:

Code
# (set $string_var to $string_value if this is non-empty, even if it is "0")  
$string_var = $default_value if !defined($string_var) ;
# or Even better
$string //= $default_value;

# (do_something if $string_var is non-empty, also if it is "0")
something( $string_var ) if defined($string_var);

#(evaluate f() if $string_var is non-empty, also if it is "0")
#(evaluate something() only if f() also returns 'true')
#(Note: f() is not evaluated unless defined() is true.)
if( defined($string_var) && f($string_var) ) { something(); }


Use of 'defined' will add little complexity to any expression.
Good Luck,
Bill


gef
New User

Jan 4, 2018, 7:09 AM

Post #3 of 6 (698 views)
Re: [BillKSmith] change string to boolean conversion [In reply to] Can't Post

thank you for your reply.

this is not what i want. if $string_var is "" then (defined $string_var) is true. i use ($string_var ne "") in order to check that $string_var is both defined AND not "".

instead of
* if $string_var ne ""
i would prefer to just write
* if $string_var
but this does not work due to the built-in conversion ("0" becomes false).

not a big deal for the second and third case anyway.

but for the first case the code is considerably more complex than what i wished for. many other combinations of boolean operators on strings (which could make the code of cascaded checks very compact) cannot be used because of the built-in assumption that "0" is false.


(This post was edited by gef on Jan 4, 2018, 7:13 AM)


BillKSmith
Veteran

Jan 4, 2018, 10:57 AM

Post #4 of 6 (690 views)
Re: [gef] change string to boolean conversion [In reply to] Can't Post

One possibility is to write your own function 'is_empty()'.

I believe the following code tests if for all the cases you have specified.


Code
C:\Users\Bill\forums\guru>type gef.pl 
use strict;
use warnings;
use Test::More tests => 3;
use constant TRUE => 1;
use constant FALSE => 0;

sub is_empty {
return TRUE if !defined $_[0];
return TRUE if $_[0] eq '';
return TRUE if $_[0] eq '0';
return FALSE;
}


my $default_string = 'DEFAULT_VALUE';
my $string_var;

subtest 'Default for empty' => sub {
plan tests => 4;
$string_var = undef;
$string_var = $default_string if is_empty($string_var);
is( $string_var, $default_string, 'undefined');

$string_var = '';
$string_var = $default_string if is_empty($string_var);
is( $string_var, $default_string, 'null string');

$string_var = 0;
$string_var = $default_string if is_empty($string_var);
is( $string_var, $default_string, 'zero');

$string_var = 'anything else';
$string_var = $default_string if is_empty($string_var);
is( $string_var, 'anything else', 'anything else');
};


our $result;
sub something {
$result = "Did something with \"$_[0]\"";
}
print "\n\n";

subtest 'Do something if string not empty' => sub {
plan tests => 4;
$string_var = undef;
$result = 'Did nothing';
something($string_var) if !is_empty($string_var);
is( $result, 'Did nothing', 'undefined');

$string_var = '';
$result = 'Did nothing';
something($string_var) if !is_empty($string_var);
is( $result, 'Did nothing', 'null string');

$string_var = 0;
$result = 'Did nothing';
something($string_var) if !is_empty($string_var);
is( $result, 'Did nothing', 'zero');

$string_var = 'anything else';
$result = 'Did nothing';
something($string_var) if !is_empty($string_var);
is( $result, "Did something with \"anything else\"", 'anything else');
};
print "\n\n";


our $result_;
sub f {
$result_ = 'Function \'f\' evaluated.';
}
subtest 'Test function if string not empty' => sub {
plan tests => 4;
$string_var = undef;
$result_ = 'Did nothing';
if( !is_empty($string_var) && f($string_var) ) { something($string_var); }
is( $result_, 'Did nothing', 'undefined');

$string_var = '';
$result_ = 'Did nothing';
if( !is_empty($string_var) && f($string_var) ) { something($string_var); }
is( $result_, 'Did nothing', 'null string');

$string_var = 0;
$result_ = 'Did nothing';
if( !is_empty($string_var) && f($string_var) ) { something($string_var); }
is( $result_, 'Did nothing', 'zero');

$string_var = 'anything else';
$result_ = 'Did nothing';
if( !is_empty($string_var) && f($string_var) ) { something($string_var); }
is( $result_, 'Function \'f\' evaluated.', 'anything else');
};

C:\Users\Bill\forums\guru>perl gef.pl
1..3
# Subtest: Default for empty
1..4
ok 1 - undefined
ok 2 - null string
ok 3 - zero
ok 4 - anything else
ok 1 - Default for empty


# Subtest: Do something if string not empty
1..4
ok 1 - undefined
ok 2 - null string
ok 3 - zero
ok 4 - anything else
ok 2 - Do something if string not empty


# Subtest: Test function if string not empty
1..4
ok 1 - undefined
ok 2 - null string
ok 3 - zero
ok 4 - anything else
ok 3 - Test function if string not empty

Good Luck,
Bill


gef
New User

Jan 4, 2018, 2:30 PM

Post #5 of 6 (684 views)
Re: [BillKSmith] change string to boolean conversion [In reply to] Can't Post

thank you for the detailed script.

i want '0' to be treated as non-empty, and the first line in is_empty() is redundant since this case is covered by the second line, so is_empty() can be modified to:


Code
sub is_empty { 
return TRUE if $_[0] eq '';
return FALSE;
}


the main inconvenience with the first test is that i have to type the variable name three times: once to set the value, and twice to assign a default value if the current value is empty. of course i can use another function to set a value or a default, like


Code
sub str_value { 
return $_[0] if $_[0] ne "";
return $_[1];
}

$string_var = str_value( $some_value, "default_value" );



BillKSmith
Veteran

Jan 5, 2018, 12:33 PM

Post #6 of 6 (655 views)
Re: [gef] change string to boolean conversion [In reply to] Can't Post

You are correct. The is_empty function in my previous post has the wrong value for the '0' case.

The following test corrects that problem and the corresponding expectations. Each major section tests my recommendation for one of your examples. It tests that code under all four conditions of 'existence'. All four conditions pass for each major test.

Code
use strict; 
use warnings;
use Test::More tests => 3;
use constant TRUE => 1;
use constant FALSE => 0;
my $default_string = 'DEFAULT_VALUE';

my $result;
my $result_;
sub is_empty;
sub something;
sub f;

subtest 'Use Default if string is empty' => sub {
my @conditions = (
# given expected description
[undef, $default_string, 'undefined'],
['', $default_string, 'null string'],
['0', '0', 'zero'],
['anything else', 'anything else', 'anything else'],
);
plan tests => scalar @conditions;

for my $condition (@conditions) {
my ($string_var, $expected, $description) = @$condition;
$string_var = $default_string if is_empty($string_var);
ok( $string_var eq $expected, $description);
}
};

subtest 'Execute function\'somethning\' unless string empty.' => sub {
my @conditions = (
# given expected description
[undef, 'did nothing', 'undefined'],
['', 'did nothing', 'null string'],
['0', 'Did function something', 'zero'],
['anything else', 'Did function something', 'execute f if string not empty'],
);
plan tests => scalar @conditions;

for my $condition (@conditions) {
my ($string_var, $expected, $description) = @$condition;
$result = 'did nothing';
something($string_var) if (!is_empty($string_var));
ok( $result eq $expected, $description);
}
};


subtest 'Test function f if string not empty.' => sub {
my @conditions = (
# given expected description
[undef, 'did nothing', 'undefined'],
['', 'did nothing', 'null string'],
['0', 'Did function f', 'zero'],
['anything else', 'Did function f', 'execute f if string not empty'],
);
plan tests => scalar @conditions;

for my $condition (@conditions) {
my ($string_var, $expected, $description) = @$condition;
$result_ = 'did nothing';
if( !is_empty($string_var) && f($string_var) ) { something($string_var); }
ok( $result_ eq $expected, $description);
}
};

sub is_empty {
return TRUE if !defined $_[0];
return TRUE if $_[0] eq '';
return FALSE if $_[0] eq '0'; # Corrrection
return FALSE;
}

sub something {
$result = "Did function something";
}

sub f {
$result_ = 'Did function f';
}


Note that these tests form a unambiguous specification of my understanding of your requirements. My recommendations (bold) test normal perl strings.


If you wish to use your new str_value function, add a test to my framework to test it. (It does appear to be correct.)

I disagree with your other comments on my is_empty function.

The first line tests for an undefined string.
The next line tests if the defined string contains only '0'.
The next line tests if the defined string is a null string.
The last line returns true for all other defined strings.
Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives