Reputation: 1776
I have a code that implements a stemming algorithm. One of the routines contain many lines similar to this one:
if(count($ret_str = $this->delete_suff(REDACTED LIST OF ARGUMENTS))) return $ret_str;
The delete_suff()
function simply returns a string (which might be the empty string), or it may return null (see code below).
Running the code on PHP 7.4 I get the warning "Parameter must be an array or an object that implements Countable", which I would like to get rid of.
On the basis of my understanding, this is what the original code does:
delete_suff()
function is called and the returned value is assigned to $ret_str
;count
'ed in order to check (if
clause) that there was actually a returned value.What is the correct way of refactoring this code to avoid such incorrect use of count()
?
On a first try I would remove the count()
altogether:
if($ret_str = $this->delete_suff(REDACTED LIST OF ARGUMENTS)) return $ret_str;
But I guess that this way the if
condition would return false when $ret_str
is empty - which would not be the original intended behavior since count('') = 1
.
A second option I came up with is:
if(!is_null($ret_str = $this->delete_suff(REDACTED LIST OF ARGUMENTS))) return $ret_str;
Which one is correct? Or, if none is correct, what would be?
EDIT: for completeness sake, this is the function that is called:
private function delete_suff($arr_suff,$str,$str_len,$where,$ovunque=false) {
if($where==='r2') $r = $this->return_R2($str);
else if($where==='rv') $r = $this->return_RV($str);
else if($where==='r1') $r = $this->return_R1($str);
$r_len = mb_strlen($r);
if($ovunque) {
foreach($arr_suff as $suff) {
if($str_len-mb_strlen($suff) < 0) continue;
$pos = mb_strpos($str,$suff,$str_len-mb_strlen($suff));
if($pos !== false) {
$pattern = '/'.$suff.'$/u';
$ret_str = preg_match($pattern,$r) ? mb_substr($str,0,$pos) : '';
if($ret_str !== '') return $ret_str;
break;
}
}
}
else {
foreach($arr_suff as $suff) {
if($r_len-mb_strlen($suff) < 0) continue;
$pos = mb_strpos($r,$suff,$r_len-mb_strlen($suff));
if($pos !== false) return mb_substr($str,0,$pos+$str_len-$r_len);
}
}
}
Upvotes: 0
Views: 135
Reputation: 54796
To refactor your code you should understand what kind of values you want to filter with if
clause.
As you say in comments - you need only strings, including empty string, so this can be stated as
if (is_string($ret_str = $this->delete_suff(REDACTED LIST OF ARGUMENTS))) return $ret_str;
Update: in provided function body I see two return
s:
return preg_match($pattern,$r) ? mb_substr($str,0,$pos) : '';
return mb_substr($str,0,$pos+$str_len-$r_len);
According to manual, mb_substr
returns string
.
Also there's one implicit return null
, when if
conditions are not met.
So, delete_suff
returns either string
or null
.
That's why you can use either is_string()
(cause null
is not string
) or use strict comparison with null
:
if (null !== (ret_str = $this->delete_suff(REDACTED LIST OF ARGUMENTS))) return $ret_str;
Which ine to use - up to you to decide. But I would use is_string
as it clearly identifies what data you need and what data should be skipped.
Upvotes: 1