2

I guess I can divide it into two questions.

1.What if I want to do something below in one single step.

if($sth->fetchrow_array is empty /undef){
    @parent = @default;
}

I tried something like this but failed.

@parent = $sth->fetchrow_array or @default;
## Problem is it assign undef if array1 is undef.

@parent = $sth->fetchrow_array || @default;
##  problem is it assign scalar value to the parent if it's not undef

2.Below is the sample code. Why I get scalar value in second output?

@default = (2,3,4);

## First output
@parent = $sth->fetchrow_array or @default;
print @parent;

##Second output;
@parent = $sth->fetchrow_array || @default;
print @parent;
2
  • if I do @parent = $sth->fetchrow_array or @default; It retuns undef If I do @parent = $sth->fetchrow_array || @default; it returns array count, not the array. Commented Aug 5, 2016 at 16:12
  • or and || evaluate their LHS operand in scalar context. Commented Aug 5, 2016 at 22:38

3 Answers 3

4

Instead of fetchrow_array I suggest that you use fetchrow_arrayref, which returns undef if there is no more data to be returned

Then you can write

@parent = @{ $sth->fetchrow_arrayref || \@default };

or, if it's convenient, you could keep the result as a reference with

$parent = $sth->fetchrow_arrayref || \@default;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, Borodin. This is what I did after giving up. But I still wanna know they way to make sure fetchrow_array never give me row with undef value.
1

@parent = $sth->fetchrow_array or @default; parses as (@parent = $sth->fetchrow_array) or @default;, which should give you this warning:

Useless use of private array in void context at foo.pl line 123.

@parent = $sth->fetchrow_array || @default; parses as @parent = ($sth->fetchrow_array || @default);, which is better. But || puts its left operand in scalar context (because it needs to check it as a boolean value) and it doesn't evaluate its left operand twice. So it ends up being the same as @parent = scalar($sth->fetchrow_array) || @default;, which is also not what you want.

You can do the following:

@parent = $sth->fetchrow_array;
@parent = @default if !@parent;

But there's no good way to do it in one statement.

1 Comment

The problem here is fetchrow_array does not return undef if no rows rather it returns a row with undef value. So the @parent = @default if !@parent; would still not work.
0
@parent = $sth->fetchrow_array  or  @parent = @default;
(@parent = $sth->fetchrow_array) || (@parent = @default);
@parent = @default unless @parent = $sth->fetchrow_array;

(this won't quite do what you want if @Shahid Siddique is correct that fetchrow_array can return an array with one undef element when the query has no results, but that hasn't been my experience)

3 Comments

Maybe I am doing something wrong while mocking. I return undef for fetchrow_array which instead returns a column with undef. $mock_sth->mock( 'fetchrow_array', sub {return undef}); NOTE that NULL fields are returned as undef in the array returned by fetchrow_array (more about NULL values later). according to this doc (easysoft.com/developer/languages/perl/…)
return undef is usually the wrong way to go precisely because in list context you would want to return () and not (undef)
Rendering NULL database values as undef in Perl makes sense, but that is a different "NULL" then the result of a database query with zero rows.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.