Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re^5: What's the right way to write a method which returns one line at a time from a file?

by Tux (Abbot)
on Nov 23, 2020 at 07:57 UTC ( #11124054=note: print w/replies, xml ) Need Help??

in reply to Re^4: What's the right way to write a method which returns one line at a time from a file?
in thread What's the right way to write a method which returns one line at a time from a file?

It is not what is executed in the else block, but what is execute after.

if (expression) { statement (1); } else { statement (2); } statement (3);

If statement (1) exits the enclosing scope with return/exit/die/croak, statement (3) is never executed. An if/else is the to do something different based on a condition and then continue doing what is after the construct for all cases. This implies that an else immediately after return/exit/die/croak is always useless.

The original code does it right in the first block:

sub get_filehandle { my $self = shift; $self->{file} = shift; open my $fh, "<", $self->{file} or die "can't open $self->{file}"; return $fh; }

Which - when following the wrong method you approve of - would be

sub get_filehandle { my $self = shift; $self->{file} = shift; if (open my $fh, "<", $self->{file}) { return $fh; } else { die "can't open $self->{file}"; } }

In my way, the second block should be reduced to

sub get_lines { my $self = shift; $self->{file} = shift; ### get the filehandle if we don't already have one $self->{file_handle} ||= $self->get_filehandle ($self->{file}); return readline ($self->{file_handle}) || undef; }

That last return is arguable anyway, as the readline method can be a method that legally can return undef, "", and 0 (or any object evaluating as false) indicating that the original code was wrong to start with.

Enjoy, Have FUN! H.Merijn
  • Comment on Re^5: What's the right way to write a method which returns one line at a time from a file?
  • Select or Download Code

Replies are listed 'Best First'.
Re^6: What's the right way to write a method which returns one line at a time from a file?
by jcb (Parson) on Nov 24, 2020 at 00:50 UTC

    While statement (3) in your example is dubious, statement (2) and its else block are completely legitimate if statements (1) and (2) both cause early exit from the block. If statement (2) does not cause an early exit, the else should be removed (or changed to a comment # else ...) and statement (2) promoted to the same position as statement (3), leaving statement (1) as a conditional early exit. If statements (1) and (2) both cause early exits, statement (3) is dead code and should be removed.

    I think I see your rationale, in that an else block can be redundant in these situations, since the entire rest of the block after a conditional early exit is effectively an "else" block without the additional indentation level. I still say that a rule that else should never be used in this context is ridiculous because it can be used to cause the indentation to line up and produce clearer code, particularly in the case where one of two (or of multiple, if elsif is used) possible return values should be chosen. In such a context, using the final else allows all of the return statements to line up at the same indentation level, producing clearer code, especially if K&R brace placement is used.

      You're almost in my lane :)

      The key for my claim is that the return/exit/die/croak is the last unconditional statement in the if block. I might have been clearer on that.

      Enjoy, Have FUN! H.Merijn

        Your rule would forbid:

        if (...) { return A } elsif (...) { return B } elsif (...) { return C } else { die "unmatched case" }

        This is why I say it is ridiculous, because I see that construct as a perfectly legitimate way to handle returning different values in different cases. The final die (or a final return undef) is indented along with all of the other cases. Omitting the else would place it one level out. Note that an if-elsif chain like this obviously can have no code following it, but the else here simply highlights that one of these will be executed. Also note that I tend to omit the semicolon after return/last/next/die/etc. in Perl because there should not be another statement after any of those and omitting the semicolon promotes such dead code to a syntax error.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://11124054]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2021-03-03 18:02 GMT
Find Nodes?
    Voting Booth?
    My favorite kind of desktop background is:

    Results (85 votes). Check out past polls.