+7  A: 

Your return is evaluated in list context because the function is called in list context. The boolean operators (like &&) do not force scalar context.

To quote perlop on &&:

Scalar or list context propagates down to the right operand if it is evaluated.

Since the match operator returns an empty list on failure in list context, that's what you get. If you want to force scalar context, use the scalar operator, either in your return statement, or when you call the function.

Also, the idea that parentheses force list context (as suggested by some of the other answers) is a common misconception. They don't. List context is the default; anything that could be list context is list context. That's why there's no list operator that corresponds to scalar. The one place where parens "force" list context is with the repetition operator. 'a' x 3 means 'aaa', but ('a') x 3 means ('a', 'a', 'a'). But that's not actually forcing list context, it's just a special case for the x operator.

cjm
$searchIn =~ $searchFor is going to return an empty array if the match fails, the parens don't matter in this case. scalar is the way to go.
Ryan M
The main reason that people think there's an association between parens and list context is that `@foo = (1, 2, 3)` does the obvious thing and `@foo = 1, 2, 3` doesn't -- but that's an *operator precedence* issue between assignment and comma.
hobbs
+2  A: 

If you want to force a "boolean context" you can use the double-negative "operator" : !!, like so:

test( !!isInString(), 'second parameter', 'third parameter' );

By calling it in a list of parameters, you've forced it into a "list context". You can force it back with something like this. One bang (!) evaluates it in a boolean context and makes it either 1 or ''. But since you aren't testing for the complement, but the value itself, putting the other bang in there gets you back the value you wanted.

However, since it's pretty clear from the function body that you are returning a boolean value, and you're calling it in a list context (a list of parameters is a list context), you might want to force a defined value there. Like so:

return ($searchFor && $searchIn && $searchIn =~ $searchFor) || 0;

Any undef will result in a false value, and it will jump to the or and return the 0, which a list context will not ignore as it can an undef.

Axeman
please see edit at the bottom of original post -removing parens yields same result, still a list context
@user210757, I fixed it, based on my own testing. Thanks.
Axeman
this makes sense. the or || method still returns list context though (0, 0), but it works. is it bad practice to use a sub call inline like this, I do this all the time in other languages
@user210757, there's nothing wrong with nested function calls. You just have to remember that they'll be called in list context unless you explicitly force scalar context. (Or a prototype does. But don't use prototypes.)
cjm
You could also do: `test( scalar isInString(), 'second parameter', 'third parameter' );` Might be clearer than `!!`. Might not. YMMV.
daotoad
If the function is supposed to return a boolean value the `return` should force it. It's bad API to expect the caller to.
Michael Carman
A: 

Not related to your question but index() is more suitable for your isInString() function.

index( $searchIn, $searchFor );
gangabass
awesome - thanks!
strange that index("abc", ""); returns 0 though, forces you to check for empty string first...