http://qs321.pair.com?node_id=11110760


in reply to Length of String

Point of order: It doesn't return null (undef in Perl terminology), it returns a special value which evaluates as an empty string when a string is expected (such as when printing) or as the number 0 when a number is expected1.

If you want to print "0" instead of an empty string, you need to force it to be used as a number first:

my $overwrite = (length($function)>1) + 0;
or use the ternary operator (which also allows you to set values other than 1/0, if you want to):
my $overwrite = length($function)>1 ? 1 : 0;
Note, though, that this is only useful for making printed output look the way you expect. The original value returned by > will work perfectly well for flow control purposes (e.g., in an if condition) without needing to be converted to a plain 0 first.

 

1 Yes, a normal empty string is also evaluated as 0 when a number is expected, but, if warnings are active, you'll get an "argument isn't numeric" warning when doing so. The "special" value returned by false boolean operators does not generate this warning.

Replies are listed 'Best First'.
Re^2: Length of String
by bigal_george (Acolyte) on Dec 30, 2019 at 17:25 UTC
    Great answers thanks. Thats a bit weird to me, that a variable can be either/or, but Ive got it now. Heres how its used in my code. Not sure if using chop is good practice, but it works..........
    my ($function, $sourcedir, $targetdir) = @ARGV; die ": missing operand. Usage: $0 <OPTION>... <SOURCE_DIRECTORY>... [T +ARGET_DIRECTORY]... OPTION all the FILE(s) and DIRECTORIES: -c = copy or -cy = copy overwrite -m = move or -my = move with overwrite -d = delete \n" unless (defined $function && defined $sourcedir); #@ARGV; #check validity input opendir(my $source_handle, $sourcedir) or die "Can't opendir $sourcedi +r: $!\n"; my $overwrite = 0 + (length $function>2) && $function =~ m/..y/ ; #strip last character ($overwrite now instantiated; no need for 'y') chop($function);

      You don't show how $overwrite is used later on, but I don't really see the need for the +0 here, since you've just got two boolean operations. But it doesn't hurt either.

      Not sure if using chop is good practice, but it works...

      chop just removes the last character from the string, so if you just want to remove the "y" from "-cy", it's perfectly fine. However, in this code, you seem to be using it unconditionally, so it would also turn "-c" into "-"...

      (length $function>2) && $function =~ m/..y/

      Note that this will also be true for strings like "silly putty". You might want to make your regex more specific by anchnoring it and limiting it to expected characters, something like /^-[cm]y$/, then you don't even need the length check. You could even combine that with removing the y like so: s/^-[cm]\Ky$// (where \K basically means "keep").

      By the way, I suggest having a look at Getopt::Long, which can take over a lot of the option processing for you, I showed an example that includes "usage" information here.

        Ohhps: $overwrite>0 && chop($function);