Perl Style and readability
Which of these two fragments is more readable?
$self->{catalina_base} = $ENV{'CATALINA_BASE'};
if (!defined $self->{catalina_base}) {
$self->{catalina_base} = $self->getTomcatHome() ;
}
if (!defined $self->{catalina_base}) {
CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3);
}
or
$self->{catalina_base} = $ENV{'CATALINA_BASE'} || $self->getTomcatHome()
|| CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3);
Update: or
$self->{catalina_base} = (
$ENV{'CATALINA_BASE'}
or $self->getTomcatHome()
or CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3)
);
7 comments
Comments are closed. These are preserved from the original site.
$self... = (
Choice1
or Choice2
or Choice3
);
Definitely, the "Update" choice was the best of the initial proposals.
Cheers.
$self->{catalina_base} = $ENV{'CATALINA_BASE'} || $self->getTomcatHome();
CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3) unless
$self->{catalina_base};
Second line should wrap, of course. And really that error message needs work. What are CATALINA_BASE and TOMCAT_HOME? What is the difference between "unset" and "undefined" and why am I supposed to care? Does that mean one is an environment variable and one is not? How am I supposed to tell? What were you trying to do at the time? (I don't want to grep the documentation for all occurences of those names.)
Testing definedness doesn't make sense; you assigned something to it right up at the top. Just test what that value is. undef is false.
Why would the third be better than the second?
As far as readability goes, I'd say that the "or" forms are easier on the eyes.
Whilst I can appreciate 'or' is more readably then '||', the use of indentation on the third example leads me to think that some kind of tuple is being assigned to $self->{catalina_base}.
You can get a // operator which does the ||-thing, but on definedness rather than truth.
I would proffer:
$self->base = (defined $ENV{'catbase'})? $ENV{'catbase'} : $self->getBase();
CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3) unless(defined $self->base);
... or something, on the basis it does the definedness test correctly, but the implicit fall-back isn't great.
BTW, the error handling is not part of the assignment, so IMHO this is even better:
$self->{catalina_base} = (
$ENV{'CATALINA_BASE'}
or $self->getTomcatHome()
) or CCM::Util::error ("CATALINA_BASE unset and TOMCAT_HOME undefined", 3);