9
\$\begingroup\$

I've gone back and forth a few times recently on my Perl coding style when it comes to module subroutines. If you have an object and you want to call the method bar with no arguments, then you can either do $foo->bar() or $foo->bar. At one point I started favoring the latter because I felt it cleaned up the code and made it more readable. However, sometimes I question whether it would be better to be fully explicit, especially considering the possibility that someone else will have to look at my code later — someone who almost certainly will not be an expert Perl programmer.

For example, consider this block of code. For the method calls that require arguments (get_tag_values and has_tag), there is no question about the parentheses. But what about next_feature and primary_tag? Is the readability I gain from dropping the parens worth losing the explicit syntax? Is one better than the other for long term maintainability? Or is this simply a subjective judgment call?

while( my $feature = $gff3->next_feature )
{
  if($type eq "cds")
  {
    if( $feature->primary_tag eq "mRNA" )
    {
      my($gene_id) = $feature->get_tag_values("Parent");
      my($mRNA_id) = $feature->get_tag_values("ID");
      next unless( $list eq '' or $genes_to_extract->{$gene_id} );
      $subseq_locations->{ $feature->seq_id }->{ $mRNA_id } = Bio::Location::Split->new();
    }
    elsif( $feature->primary_tag eq "CDS" )
    {
      my($mRNA_id) = $feature->get_tag_values("Parent");
      if( $subseq_locations->{ $feature->seq_id }->{ $mRNA_id } )
      {
        $subseq_locations->{ $feature->seq_id }->{ $mRNA_id }->add_sub_Location( $feature->location );
      }
    }
  }
  else
  {
    if( $feature->primary_tag eq $type )
    {
      my $feat_id;
      if( $list ne '')
      {
        ($feat_id) = $feature->get_tag_values("ID") if($feature->has_tag("ID"));
        next unless( $feature->has_tag("ID") and $genes_to_extract->{$feat_id} );
      }
      $subseq_locations->{ $feature->seq_id }->{ $feat_id } = Bio::Location::Split->new();
      $subseq_locations->{ $feature->seq_id }->{ $feat_id }->add_sub_Location( $feature->location );
    }
  }
}
\$\endgroup\$
  • \$\begingroup\$ It's a very good idea not to underestimate the importance of readability to others, most probably not so informed about the aim of the program and/or the language. Especially because most of the time, the other person is future you. \$\endgroup\$ – Alois Mahdal Aug 8 '12 at 21:15
10
\$\begingroup\$

Because either is technically acceptable, you are right that it is a style issue and simply a case of choosing a coding convention.

However, I think that you have hit a very important point. So few other languages that use parentheses for functions allow a parameterless function call without parentheses that it can be very surprising for developers unfamiliar to perl.

This point would sway me in favour of always using them and, indeed, I always do so out of habit because I use other languages a lot and it just comes naturally.

\$\endgroup\$
13
\$\begingroup\$

I prefer to make a distinction on semantic level: there are no functions or methods, but instead there are properties and actions. Every property is an object (in real-world sense) and an action is something done on an object. A good mnemonic is probably to read () as do it!.

Consider a variable:

$document

You know by the name it's an object, since it's a noun.

$document->author

Even though author is probably a function/method, an author is an object and a noun, so it's a property and thus no parens here.

$document->send()
$document->author->write_book()

Again, send and write_book are functions/methods, but since those are actions (as designated by verbs), we write parens behind them.

$document->author_count
$document->has_reviews

Again, a function/method, but a property of a document object, not an action, so no parens. A boolean value or an integer is strictly speaking not a real-world object, but it's more like an object than an action.

\$\endgroup\$
3
\$\begingroup\$

To me, it is a no-brainer (for all it is a style question); retain the empty parentheses for the function call.

The language I've used that allows (requires?) functions with no arguments to be called without parentheses was Pascal, and I always found such calls confusing - doubly so when invoked in the argument list to another function.

Perl no longer requires the & in front of functions as it once did. I think it is still worth distinguishing between a variable reference and a function call by providing the parentheses, at least when the call could be confused with a variable reference.

\$\endgroup\$
3
\$\begingroup\$

There really are very few things that can follow ->, that I don't think of it as much of an issue.

  • $obj->method
  • $obj->method()
  • $code->()
  • $hash->{element}
  • $array->[0]
  • m<->xmsg
  • q<->.'text'

The only reasonably possible confusion that I can come up with is that someone might think that methods and subroutine calls are parsed the same.

$obj->method(subroutine());
$obj->method subroutine(); # error

subroutine $obj->method;
subroutine($obj->method); # same as above (usually)

Most beginners start by looking at example code they find on the internet. Those examples may very well have both styles in them. So people wanting to learn Perl, will eventually need to know that they are equivalent. Probably sooner, rather than later.


That being said, go ahead and standardize on one style or the other. Do it because you like that style, not because it might possibly one-day help people learn Perl.

\$\endgroup\$
  • \$\begingroup\$ "Do it because you like that style, not because it might possibly one-day help people learn Perl." I'd rather say: Do it (and like it) because it can help people read your code. Most importantly, do not forget that the other person reading code will be you. \$\endgroup\$ – Alois Mahdal Aug 8 '12 at 21:11
  • \$\begingroup\$ @AloisMahdal If you like a style, it is probably because you find it easier to understand. \$\endgroup\$ – Brad Gilbert Aug 9 '12 at 0:09
2
\$\begingroup\$

It depends on the purpose. I prefer parenthesis for "real" methods, doing something. For properties with at most small getter/setter and simple checks I use the shorter version.

\$\endgroup\$
  • \$\begingroup\$ Setters have to have parenthesis. Only parameterless method calls can omit the parenthesis. \$\endgroup\$ – Frank Szczerba Jan 27 '12 at 15:05
2
\$\begingroup\$

I appreciate code that is more explicit, and having those parentheses would help me to use your code. I am learning more about Perl, and any hints that help me to understand the meaning of the letters, numbers, and symbols in a program are welcome. Adding the extra notation will help beginners, and won't stop experts.

On the other hand, many Perl idioms can be efficient, but are terse and often obscure; their use can delay or stop a beginner.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.